--- cdrtools-3.00/mkisofs/mkisofs.c.orig Tue Jun 28 15:31:06 2011
+++ cdrtools-3.00/mkisofs/mkisofs.c Tue Jun 28 15:32:46 2011
@@ -66,7 +66,7 @@
struct directory *root = NULL;
int path_ind;
-char version_string[] = VERSION;
+char version_string[] = VERSION "+eltorito-platform";
char *outfile;
FILE *discimage;
@@ -110,6 +110,8 @@
int osecsize = 0; /* Output-sector size, 0 means default secsize 2048 */
int use_Joliet = 0;
int jlen = JMAX; /* maximum Joliet file name length */
+
+int def_platid = EL_TORITO_ARCH_x86;
/*
* Verbose levels currently used:
*
@@ -182,6 +184,7 @@
int help; /* CLI Parameter for -help option */
int joliet_long; /* CLI Parameter for -joliet-long option */
char *jcharset; /* CLI Parameter for -jcharset option */
+char *modification_date; /* CLI Parameter for -modification-date */
int max_filenames; /* CLI Parameter for -max-iso9660-filenames option */
char *log_file; /* CLI Parameter for -log-file option */
char *dir_mode_str; /* CLI Parameter for -new-dir-mode option */
@@ -446,7 +449,374 @@
return (1);
}
+#define IS_SEPARATOR1(c) (c == '/' || c == '-')
+
+LOCAL boolean_t
+isalldigits(char *p, int n)
+{
+ int i;
+ if (p == NULL)
+ return (B_FALSE);
+ for (i = 0; i < n; i++) {
+ if (p[i] == 0)
+ return (B_FALSE);
+ if ((p[i] < '0') || (p[i] > '9'))
+ return (B_FALSE);
+ }
+ return (B_TRUE);
+}
+
+LOCAL char *
+findnextsep(char *p, char *matches)
+{
+ char *mp;
+ while (*p) {
+ if (matches == NULL) {
+ if ((*p < '0') || (*p > '9'))
+ return (p);
+ } else {
+ mp = matches;
+ while (*mp) {
+ if (*mp == *p)
+ return (p);
+ mp++;
+ }
+ }
+ p++;
+ }
+ if (*p == NULL)
+ return (NULL);
+ return (p);
+}
+
+LOCAL boolean_t
+check_n_get_val(char *s, int n, long *val, int checklower, long lower,
+int checkupper, long upper)
+{
+ char c;
+ long l;
+
+ if (isalldigits(s, n) != B_TRUE)
+ return (B_FALSE);
+
+ if (n > 20)
+ return (B_FALSE);
+
+ c = *(s+n);
+ *(s + n) = 0;
+
+ errno = 0;
+ l = strtol(s, NULL, 10);
+
+ *(s+n) = c;
+
+ if (errno)
+ return (B_FALSE);
+
+ if (val != NULL)
+ *val = l;
+
+ if (checklower)
+ if (l < lower)
+ return (B_FALSE);
+ if (checkupper)
+ if (l > upper)
+ return (B_FALSE);
+
+ return (B_TRUE);
+}
+
LOCAL int
+get_gmt()
+{
+ time_t now;
+ struct tm gmt, *gmp, *localp, localt;
+ time_t gmtoffsetsec = 0;
+
+ now = time(NULL);
+ if (now == -1)
+ comerrno(EX_BAD, "time failed internal error\n");
+
+ localp = localtime(&now);
+ if (localp == NULL)
+ comerrno(EX_BAD, "localtime failed internal error\n");
+
+ localt = *localp;
+
+ gmp = gmtime(&now);
+ if (gmp == NULL)
+ comerrno(EX_BAD, "gmtime failed internal error\n");
+
+ gmt = *gmp;
+
+ gmtoffsetsec = mktime(&localt) - mktime(&gmt);
+
+ return ((int)(gmtoffsetsec /(60 * 15)));
+}
+
+
+
+char modbuf[18];
+LOCAL int
+get_modification_date(opt_arg)
+ char *opt_arg;
+{
+ int len;
+ char *optp = opt_arg;
+ char *dotp = NULL;
+ char *signp = NULL;
+ char *bufp = modbuf;
+ char *tmpp = NULL;
+ char *default_mod = "00010101000000000";
+ char tmpstr[5];
+ int gmtset = 0;
+
+ strncpy(modbuf, default_mod, 17);
+ modbuf[17] = 0;
+
+
+ len = strlen(opt_arg);
+
+ /* first find the gmt */
+ tmpp = strrchr(optp, '+');
+
+ if (tmpp != NULL || ((tmpp = strrchr(optp, '-')) != NULL)) {
+ /* it has to be the last 4 digits */
+ if ((tmpp - optp) != (len - 5)) {
+ if (*tmpp == '+')
+ comerrno(EX_BAD, "Bad modification date\n");
+ /* if '-' take it as a separator */
+ } else {
+ long gh, gm, val;
+ if (check_n_get_val(tmpp + 1, 2, &gh, 0, 0, 0, 0)
+ != B_TRUE)
+ comerrno(EX_BAD, "Bad modification date:gh\n");
+
+ if (check_n_get_val(tmpp + 3, 2, &gm, 0, 0, 0, 0)
+ != B_TRUE)
+ comerrno(EX_BAD, "Bad modification date:gm\n");
+
+ val = (((gh * 60) + gm) / 15) *
+ ((*tmpp == '-') ? -1 : 1);
+
+
+ if (val < -48 || val > 52)
+ comerrno(EX_BAD, "Bad modification date:"
+ " gmt offset\n");
+ modbuf[16] = val;
+ gmtset = 1;
+
+ /* get rid of gmt in input str, we are done with it */
+ *tmpp = 0;
+ }
+ }
+ if (gmtset == 0) {
+ modbuf[16] = get_gmt();
+ }
+
+ len = strlen(optp);
+
+ if ((tmpp = strrchr(optp, '.')) != NULL) {
+
+ if ((tmpp - optp) != (len - 3)) {
+ comerrno(EX_BAD, "Bad modification date:hundredth "
+ "of sec\n");
+ }
+
+ if (check_n_get_val(tmpp + 1, 2, NULL, 0, 0, 0, 0) != B_TRUE)
+ comerrno(EX_BAD, "Bad modification date:hundredth of"
+ " second length\n");
+
+ /* since all digits, can not be > 99 */
+ modbuf[14] = *(tmpp + 1);
+ modbuf[15] = *(tmpp + 2);
+
+ /* get rid of hh in input str, we are done with it */
+ *tmpp = 0;
+ }
+
+ tmpp = findnextsep(optp, "/-");
+
+ if (tmpp) {
+ if (tmpp - optp == 2) {
+ long year;
+ /* 2 digit year YY- */
+ if (check_n_get_val(optp, 2, &year, 0, 0, 0, 0)
+ != B_TRUE)
+ comerrno(EX_BAD, "Bad modification date:year"
+ "length \n");
+ /* 69-99 1969-1999, 00-68 2000 to 2068 */
+ if (year > 68)
+ strncpy(bufp, "19", 2);
+ else
+ strncpy(bufp, "20", 2);
+ bufp += 2;
+ strncpy(bufp, optp, 2);
+ bufp += 2;
+ optp = tmpp + 1;
+
+ } else if (tmpp - optp == 4) {
+ long year;
+
+ /* 4 digit year YYYY- */
+ if (check_n_get_val(optp, 4, &year, 1, 1, 0, 0)
+ != B_TRUE)
+ comerrno(EX_BAD, "Bad modification date:"
+ "year\n");
+ strncpy(bufp, optp, 4);
+ bufp += 4;
+ optp = tmpp + 1;
+
+ } else if (tmpp - optp == 6) {
+ /* YYYYMM- */
+ long year;
+ if (isalldigits(optp, 6) != B_TRUE)
+ comerrno(EX_BAD, "Bad modification date: "
+ "year\n");
+
+ if (check_n_get_val(optp, 4, &year, 1, 1, 0, 0)
+ != B_TRUE)
+ comerrno(EX_BAD, "Bad modification date: year "
+ "length\n");
+
+ strncpy(bufp, optp, 4);
+ optp = optp + 4;
+ bufp += 4;
+ } else
+ comerrno(EX_BAD, "Bad modification date\n");
+
+ } else /* tmpp == NULL */ {
+ /* YYYY[MM[DD.... */
+ long year;
+
+ if (check_n_get_val(optp, 4, &year, 1, 1, 0, 0) != B_TRUE)
+ comerrno(EX_BAD, "Bad modification date year:length\n");
+
+ strncpy(bufp, optp, 4);
+ bufp += 4;
+ optp += 4;
+ }
+
+ if (*optp) {
+ long month;
+ /* optp should point to MM */
+ if (check_n_get_val(optp, 2, &month, 1, 1, 1, 12) != B_TRUE)
+ comerrno(EX_BAD, "Bad modification date:month\n");
+ strncpy(bufp, optp, 2);
+ bufp += 2;
+ optp += 2;
+ }
+ if ((*optp) && (IS_SEPARATOR1(*optp)))
+ optp++;
+
+ if (*optp) {
+ long day;
+
+ if (check_n_get_val(optp, 2, &day, 1, 1, 1, 31) != B_TRUE)
+ comerrno(EX_BAD, "Bad modification date: day\n");
+ /* DD */
+ strncpy(bufp, optp, 2);
+ bufp += 2;
+ optp += 2;
+ }
+
+ if (*optp == ' ')
+ optp++;
+
+ if (*optp) {
+ long hour;
+ if (check_n_get_val(optp, 2, &hour, 0, 0, 1, 23) != B_TRUE)
+ comerrno(EX_BAD, "Bad modification date: hour\n");
+
+ strncpy(bufp, optp, 2);
+ bufp += 2;
+ optp += 2;
+ }
+
+ if (*optp == ':')
+ optp++;
+
+ if (*optp) {
+ long min;
+ if (check_n_get_val(optp, 2, &min, 0, 0, 1, 59) != B_TRUE)
+ comerrno(EX_BAD, "Bad modification date: minute\n");
+ strncpy(bufp, optp, 2);
+ bufp += 2;
+ optp += 2;
+ }
+
+ if (*optp == ':')
+ optp++;
+
+ if (*optp) {
+ long sec;
+ if (check_n_get_val(optp, 2, &sec, 0, 0, 1, 59) != B_TRUE)
+ comerrno(EX_BAD, "Bad modification date: second\n");
+ strncpy(bufp, optp, 2);
+ bufp += 2;
+ optp += 2;
+ }
+
+ if (*optp == ' ')
+ /* optional space */
+ optp++;
+
+ if (*optp != 0) {
+ comerrno(EX_BAD, "Bad modification date: extra \n");
+ }
+
+ modification_date = modbuf;
+ return (1);
+
+}
+
+
+LOCAL int
+get_boot_platid(opt_arg)
+ char *opt_arg;
+{
+ long val;
+ char *ptr;
+
+ use_eltorito++;
+
+ if (strcmp(opt_arg, "x86") == 0)
+ val = 0;
+ else if (strcmp(opt_arg, "PPC") == 0)
+ val = 1;
+ else if (strcmp(opt_arg, "Mac") == 0)
+ val = 2;
+ else if (strcmp(opt_arg, "efi") == 0)
+ val = 0xEF;
+ else {
+ val = strtol(opt_arg, &ptr, 0);
+ if (*ptr || val < 0 || val >= 0x100) {
+ comerrno(EX_BAD, "Bad boot system ID.\n");
+ }
+ }
+
+ if (boot_image == NULL) {
+ /* called before -eltorito-boot option */
+ def_platid = val;
+ return (1);
+
+ }
+
+ if (val != def_platid) {
+ new_boot_entry();
+ get_boot_entry();
+ }
+
+ if (current_boot_entry == NULL)
+ comerrno(EX_BAD, "No current boot entry.\n");
+
+ current_boot_entry->type = ELTORITO_SECTION_HEADER;
+ current_boot_entry->boot_platid = val;
+
+ return (1);
+}
+
+LOCAL int
get_boot_size(opt_arg)
char *opt_arg;
{
@@ -840,7 +1210,8 @@
"Allow full 31 character filenames for ISO9660 names"},
{{"max-iso9660-filenames", &max_filenames },
"Allow 37 character filenames for ISO9660 names (violates ISO9660)"},
-
+ {{"modification-date&", NULL, (getpargfun)get_modification_date},
+ "\1[string]\1Set the modification date in the primary volume descriptor"},
{{"allow-leading-dots", &allow_leading_dots },
"Allow ISO9660 filenames to start with '.' (violates ISO9660)"},
{{"ldots", &allow_leading_dots },
@@ -968,6 +1339,8 @@
"Boot image is 'no emulation' image"},
{{"no-boot~", NULL, (getpargfun)get_no_boot },
"Boot image is not bootable"},
+ {{"eltorito-platform&", NULL, (getpargfun)get_boot_platid },
+ "\1#\1Set eltorito platform id"},
{{"boot-load-seg&", NULL, (getpargfun)get_boot_addr },
"\1#\1Set load segment for boot image"},
{{"boot-load-size&", NULL, (getpargfun)get_boot_size },