From 9ea76568f6770b6da536bd384c1638f6592fd244 Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Sat, 29 Jun 2024 18:28:33 +0200 Subject: [PATCH] New address modes 5 to 7 for isoburn_set_msc1(), isoburn_get_mount_params(), isoburn_get_mount_params_v2() --- libisoburn/burn_wrap.c | 138 ++++++++++++++++++++++++++++++++---- libisoburn/libisoburn.h | 20 ++++++ xorriso/xorriso_timestamp.h | 2 +- 3 files changed, 146 insertions(+), 14 deletions(-) diff --git a/libisoburn/burn_wrap.c b/libisoburn/burn_wrap.c index c6f8d4e5..97ec6063 100644 --- a/libisoburn/burn_wrap.c +++ b/libisoburn/burn_wrap.c @@ -2090,26 +2090,116 @@ int isoburn_drive_set_msgs_submit(struct burn_drive *d, return(1); } + +/* YYYYMMDDhhmmsscc[LOC] */ +/* 2010040711405800 */ +static int isoburn_mktime_ecma119_time17(struct tm *erg, char *text, int flag) +{ + int i, l, num, utc= 1; + struct tm norm_tm; + + memset(erg, 0, sizeof(*erg)); + erg->tm_isdst= -1; + l= strlen(text); + if(l == 19) { + if(strcmp(text + 16, "LOC") != 0) + return(0); + utc= 0; + l= 16; + } + if(l != 16) + return(0); + for(i= 0; i < l; i++) + if(text[i] < '0' || text[i] > '9') + return(0); + num= 0; + for(i= 0; i < 4; i++) + num= num * 10 + text[i] - '0'; + if(num < 1970 || num > 3000) + return(0); + erg->tm_year = num - 1900; + erg->tm_mon= 10*(text[4]-'0')+text[5]-'0'-1; + if(erg->tm_mon > 12) + return(0); + erg->tm_mday= 10*(text[6]-'0')+text[7]-'0'; + if(erg->tm_mday > 31) + return(0); + erg->tm_hour= 10*(text[8]-'0')+text[9]-'0'; + if(erg->tm_hour > 23) + return(0); + erg->tm_min= 10*(text[10]-'0')+text[11]-'0'; + if(erg->tm_min > 59) + return(0); + erg->tm_sec= 10*(text[12]-'0')+text[13]-'0'; + if(erg->tm_sec > 59) + return(0); + /* Let mktime(3) compute erg->tm_wday and erg->tm_yday */ + memcpy(&norm_tm, erg, sizeof(struct tm)); + mktime(&norm_tm); + erg->tm_wday= norm_tm.tm_wday; + erg->tm_yday= norm_tm.tm_yday; + return(1 + !utc); +} + + +/* Convert to time_t: + YYYYMMDDhhmmssccN (N = 15 minutes Offset from GMT: -48 West to +52 east) +*/ +static int isoburn_decode_ecma119_time17(time_t *seconds, char *code, int flag) +{ + int ret; + char digits[17]; + struct tm erg; + + *seconds= 0; + strncpy(digits, code, 16); + digits[16]= 0; + ret= isoburn_mktime_ecma119_time17(&erg, digits, 0); + if(ret <= 0) + return(ret); + *seconds= mktime(&erg); + + /* Revert ECMA-119 timezone offset */ + *seconds-= (int) code[16] * 60 * 15; + + /* Convert from local time to GMT */ +#ifdef HAVE_TM_GMTOFF + *seconds+= erg.tm_gmtoff; +#else + if(erg.tm_isdst < 0) + erg.tm_isdst = 0; +#ifndef Libburnia_timezonE +#define Libburnia_timezonE timezone +#endif + *seconds-= Libburnia_timezonE - erg.tm_isdst * 3600; +#endif + + return(1); +} + /* @param flag bit0= with adr_mode 3: adr_value might be 16 blocks too high bit1= insist in seeing a disc object with at least one session bit2= with adr_mode 4: use adr_value as regular expression + with adr_mode 5 to 7: use creation time rather than + modification time */ int isoburn_set_msc1(struct burn_drive *d, int adr_mode, char *adr_value, int flag) { int ret, num_sessions= 0, num_tracks, i, j, total_tracks; - int re_valid= 0, track_count= 0; + int re_valid= 0, track_count= 0, info_type; off_t adr_num, lba, best_lba, size; double adr_double; - time_t start_time= 0, last_pacifier= 0, now; + time_t start_time= 0, last_pacifier= 0, now, seconds; char volid[33], *msg= NULL; struct isoburn *o; struct isoburn_toc_disc *disc= NULL; struct isoburn_toc_session **sessions= NULL; struct isoburn_toc_track **tracks= NULL; - static char mode_names[][20]= {"auto", "session", "track", "lba", "volid"}; - static int max_mode_names= 4; + static char mode_names[][20]= {"auto", "session", "track", "lba", "volid", + "at_time", "not_after", "not_before"}; + static int max_mode_names= 7; regex_t re; regmatch_t match[1]; enum burn_disc_status s; @@ -2136,7 +2226,8 @@ int isoburn_set_msc1(struct burn_drive *d, int adr_mode, char *adr_value, not_found:; if(adr_mode<0 || adr_mode>max_mode_names) goto unknown_mode; - sprintf(msg, "Failed to find %s %s", mode_names[adr_mode], + sprintf(msg, "Failed to find \"%s\" \"%s%s\"", mode_names[adr_mode], + adr_mode >= 5 && adr_mode <= 7 ? "=" : "", strlen(adr_value)<=80 ? adr_value : "-oversized-string-"); isoburn_msgs_submit(o, 0x00060000, msg, 0, "FAILURE", 0); ret= 0; goto ex; @@ -2196,9 +2287,9 @@ not_found:; if(ret==2) o->fabricated_msc1-= 16; } - } else if(adr_mode==4) { + } else if(adr_mode >= 4 && adr_mode <= 7) { /* search for volume id that is equal to adr_value */ - if(flag & 4) { + if(adr_mode == 4 && (flag & 4)) { ret= regcomp(&re, adr_value, 0); if(ret != 0) flag&= ~4; @@ -2223,25 +2314,46 @@ not_found:; ret= isoburn_toc_track_get_emul_v2(tracks[0], &lba, &size, volid, 0); if(ret < 0) continue; - if(ret == 0) { + if(ret == 0 || (adr_mode >= 5 && adr_mode <= 7)) { isoburn_get_track_lba(tracks[0], &lba, 0); - ret= isoburn_read_iso_head_v2(d, lba, &size, volid, 1); + info_type= (adr_mode == 4 ? 1 : 3 + !!(flag & 4)); + ret= isoburn_read_iso_head_v2(d, lba, &size, volid, info_type); if(ret<=0) continue; } - if(flag & 4) { - ret= regexec(&re, volid, 1, match, 0); - if(ret != 0) + if(adr_mode == 4) { + if(flag & 4) { + ret= regexec(&re, volid, 1, match, 0); + if(ret != 0) continue; + } else { + if(strcmp(volid, adr_value)!=0) + continue; + } } else { - if(strcmp(volid, adr_value)!=0) + /* Convert volid text to seconds GMT */ + ret= isoburn_decode_ecma119_time17(&seconds, volid, 0); + if(ret <= 0) continue; + if(adr_mode == 5) { + if(seconds != (time_t) adr_num) + continue; + } else if(adr_mode == 6) { + if(seconds > (time_t) adr_num) + continue; + } else if(adr_mode == 7) { + if(seconds >= (time_t) adr_num) { + best_lba= lba; + goto take_best_lba; + } + } } best_lba= lba; } } if(best_lba<0) goto not_found; +take_best_lba:; o->fabricated_msc1= best_lba; } else { diff --git a/libisoburn/libisoburn.h b/libisoburn/libisoburn.h index 1b9e50ae..99516e86 100644 --- a/libisoburn/libisoburn.h +++ b/libisoburn/libisoburn.h @@ -552,6 +552,14 @@ void isoburn_disc_erase(struct burn_drive *drive, int fast); 3= adr_value itself is the lba to be used 4= start lba of last session with volume id given by adr_value + @since 1.5.8 : + 5= start lba of last session with modification time + exactly as given by adr_value. adr_value is seconds + since 1970 GMT (i.e. time_t as decimal number string) + 6= start lba of last session with modification time + not after adr_value (seconds after 1970 GMT) + 7= start lba of first session with modification time + not before adr_value (seconds after 1970 GMT) @param adr_value A string describing the value to be eventually used. @param flag Bitfield for control purposes. bit0= @since 0.2.2 @@ -560,6 +568,8 @@ void isoburn_disc_erase(struct burn_drive *drive, int fast); at adr_value-16 and eventually adjust setting. bit1= insist in seeing a disc object with at least one session bit2= with adr_mode 4: use adr_value as regular expression + with adr_mode 5 to 7: use creation time rather than + modification time */ int isoburn_set_msc1(struct burn_drive *d, int adr_mode, char *adr_value, int flag); @@ -784,6 +794,14 @@ int isoburn_read_iso_head_v2(struct burn_drive *d, off_t lba, 3= adr_value itself is the lba to be used 4= start lba of last session with volume id given by adr_value + @since 1.5.8 : + 5= start lba of last session with modification time + exactly as given by adr_value. adr_value is seconds + since 1970 GMT (i.e. time_t as decimal number string) + 6= start lba of last session with modification time + not after adr_value (seconds after 1970 GMT) + 7= start lba of first session with modification time + not before adr_value (seconds after 1970 GMT) @param adr_value A string describing the value to be eventually used. @param lba returns the block address of the entity, -1 means invalid @param track returns the track number of the entity, -1 means invalid @@ -791,6 +809,8 @@ int isoburn_read_iso_head_v2(struct burn_drive *d, off_t lba, @param volid returns the volume id of the entity if it is a ISO session @param flag Bitfield for control purposes. bit2= with adr_mode 4: use adr_value as regular expression + with adr_mode 5 to 7: use creation time rather than + modification time @return <=0 error , 1 ok, ISO session, 2 ok, not an ISO session */ int isoburn_get_mount_params(struct burn_drive *d, diff --git a/xorriso/xorriso_timestamp.h b/xorriso/xorriso_timestamp.h index adaa80c1..47cdc73f 100644 --- a/xorriso/xorriso_timestamp.h +++ b/xorriso/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2024.06.28.144204" +#define Xorriso_timestamP "2024.06.29.162751"