17 #include "../config.h"
47 #ifdef Libisofs_syslinux_tesT
48 #define Isolinux_rockridge_in_libisofS 1
49 #include "/reiser/syslinux/core/fs/iso9660/susp_rr.c"
439 #ifdef Libisofs_with_zliB
440 uint8_t zisofs_algo[2];
441 uint8_t header_size_div4;
442 uint8_t block_size_log2;
443 uint64_t uncompressed_size;
483 while (
next != NULL) {
497 if (data->
parent == NULL) {
500 char *path, *new_path;
503 if (data->
name == NULL)
508 pathlen = strlen(path);
509 new_path = realloc(path, pathlen + strlen(data->
name) + 2);
510 if (new_path == NULL) {
516 path[pathlen + 1] =
'\0';
517 return strcat(path, data->
name);
526 return data->
name == NULL ? NULL : strdup(data->
name);
534 if (src == NULL || info == NULL) {
550 if (src == NULL || info == NULL || src->
data == NULL) {
556 if (S_ISLNK(data->
info.st_mode)) {
608 tlen += record->
len_dr[0];
613 tlen += record->
len_dr[0];
616 while (tlen < size) {
619 if (pos == 2048 || record->
len_dr[0] == 0) {
641 #ifdef Libisofs_wrongly_skip_rr_moveD
658 && !strncmp((
char*)record->
file_id,
"RR_MOVED", 8)) {
662 tlen += record->
len_dr[0];
707 tlen += record->
len_dr[0];
723 if (src == NULL || src->
data == NULL) {
732 if (S_ISDIR(data->
info.st_mode)) {
755 }
else if (S_ISREG(data->
info.st_mode)) {
779 if (src == NULL || src->
data == NULL) {
797 }
else if (data->
opened == 1) {
822 if ( (offset - bytes) < (off_t) sections[section].size ) {
825 bytes += (off_t) sections[section].size;
829 }
while(section < nsections);
844 if ( (offset - bytes) < (off_t) sections[section].size ) {
845 uint32_t curr_section_offset = (uint32_t)(offset - bytes);
846 uint32_t curr_section_left = sections[section].
size - curr_section_offset;
848 return MIN(curr_section_left, available);
850 bytes += (off_t) sections[section].size;
854 }
while(section < nsections);
870 if ( (offset - bytes) < (off_t) sections[section].size ) {
871 return (uint32_t)(offset - bytes) %
BLOCK_SIZE;
873 bytes += (off_t) sections[section].size;
877 }
while(section < nsections);
906 if (src == NULL || src->
data == NULL || buf == NULL) {
916 }
else if (data->
opened != 1) {
920 while (read < count && data->data.
offset < data->
info.st_size) {
951 memcpy((uint8_t*)buf + read, orig, bytes);
966 if (offset < (off_t)0) {
974 }
else if (data->
opened != 1) {
1023 if (src == NULL || src->
data == NULL || child == NULL) {
1030 }
else if (data->
opened != 2) {
1040 *child = children->
file;
1084 if (src == NULL || buf == NULL || src->
data == NULL) {
1094 if (!S_ISLNK(data->
info.st_mode)) {
1102 if (len >= bufsiz) {
1106 strncpy(buf, dest, len);
1137 if (S_ISLNK(data->
info.st_mode)) {
1141 if (data->
parent != NULL) {
1161 if ((flag & 1) || data->
aa_string == NULL) {
1166 *aa_string = calloc(len, 1);
1167 if (*aa_string == NULL)
1169 memcpy(*aa_string, data->
aa_string, len);
1180 char *new_name = NULL;
1182 void *new_aa_string = NULL;
1193 new_name = strdup(old_data->
name);
1194 if (new_name == NULL)
1198 if (new_data == NULL)
1201 new_sections = calloc(old_data->
nsections,
1203 if (new_sections == NULL)
1210 new_data->
fs = old_data->
fs;
1214 memcpy(&(new_data->
info), &(old_data->
info),
sizeof(
struct stat));
1215 new_data->
name = new_name;
1218 for (i = 0; i < new_data->
nsections; i++)
1222 #ifdef Libisofs_with_zliB
1223 new_data->header_size_div4 = old_data->header_size_div4;
1224 new_data->block_size_log2 = old_data->block_size_log2;
1225 new_data->uncompressed_size = old_data->uncompressed_size;
1228 new_data->
aa_string = (
unsigned char *) new_aa_string;
1232 src->
data = new_data;
1240 if (new_data != NULL)
1241 free((
char *) new_data);
1242 if (new_name != NULL)
1244 if (new_sections != NULL)
1245 free((
char *) new_sections);
1246 if (new_aa_string != NULL)
1276 int *header_size_div4,
int *block_size_log2,
1277 uint64_t *uncompressed_size,
int flag)
1280 #ifdef Libisofs_with_zliB
1287 zisofs_algo[0] = data->zisofs_algo[0];
1288 zisofs_algo[1] = data->zisofs_algo[1];
1289 *header_size_div4 = data->header_size_div4;
1290 *block_size_log2 = data->block_size_log2;
1291 *uncompressed_size = data->uncompressed_size;
1304 char *str,
size_t len,
char **name)
1306 int ret, name_len, i;
1307 char c, *smashed = NULL, md5[16];
1308 void *md5_context = NULL;
1315 name_len = len > 223 ? 223 : len;
1317 memcpy(smashed, str, name_len);
1318 for (; name_len < 8; name_len++)
1319 smashed[name_len] =
'_';
1320 smashed[name_len] = 0;
1321 for (i = 0; i < name_len; i++) {
1323 if (c ==
'.' || (c >=
'0' && c <=
'9') ||
1324 c ==
'_' || (c >=
'a' && c <=
'z'))
1337 for (i = 0; i < 16; i++)
1338 sprintf(smashed + i * 2 + name_len,
"%2.2x",
1339 ((
unsigned char *) md5)[i]);
1341 smashed[name_len] = 0;
1342 *name = smashed; smashed = NULL;
1347 if (md5_context != NULL)
1361 char *name = NULL, *from_ucs = NULL;
1373 ret = (strcmp(name, from_ucs) == 0);
1379 "Joliet filename valid only with character set UTF-16 : \"%s\"",
1383 if (from_ucs != NULL)
1389 "Cannot convert from charset %s to %s",
1404 name = malloc(len + 1);
1408 memcpy(name, str, len);
1416 int errcode,
int causedby,
const char *msg)
1428 "MORE THAN ONCE : %s", msg);
1457 int ret, ecma119_map, skip_nm = 0;
1469 int linkdestcont = 0;
1470 char *linkdest = NULL;
1472 uint32_t relocated_dir = 0;
1474 unsigned char *aa_string = NULL;
1475 size_t aa_size = 0, aa_len = 0, prev_field = 0;
1483 #ifdef Libisofs_with_zliB
1484 uint8_t zisofs_alg[2], zisofs_hs4 = 0, zisofs_bsl2 = 0;
1485 uint64_t zisofs_usize = 0;
1488 if (fs == NULL || fs->
data == NULL || record == NULL || src == NULL) {
1494 memset(&atts, 0,
sizeof(
struct stat));
1498 if (record->
flags[0] & 0x02) {
1499 atts.st_mode = S_IFDIR;
1501 atts.st_mode = S_IFREG;
1511 "Unsupported image. This image has at least one file recorded "
1512 "in interleaved mode. We do not support this mode, as we think "
1513 "it is not used. If you are reading this, then we are wrong :) "
1514 "Please contact libisofs developers, so we can fix this.");
1527 if (new_name == NULL) {
1529 "Cannot retrieve file name");
1532 if (strcmp(new_name, data->
name)) {
1534 "Multi-extent file lacks last entry.");
1542 if (record->
flags[0] & 0x80) {
1548 if ((record->
flags[0] & 0x02) || (flag & 1)) {
1550 "Directories with more than one section are not allowed.");
1556 if (ifsdata == NULL) {
1561 if (ifsrc == NULL) {
1565 ifsrc->
data = ifsdata;
1567 if (ifsdata->
name == NULL) {
1569 "Cannot retrieve file name");
1576 ifsdata = (*src)->
data;
1583 free(ifsdata->
name);
1609 fsdata->session_lba + fsdata->nblocks,
1610 fsdata->len_skp, fsdata->msgid);
1628 "Invalid PX entry");
1629 fsdata->px_ino_status |= 8;
1631 if (fsdata->inode_counter < atts.st_ino)
1632 fsdata->inode_counter = atts.st_ino;
1633 fsdata->px_ino_status |= 1;
1636 fsdata->px_ino_status |= 2;
1639 }
else if (
SUSP_SIG(sue,
'T',
'F')) {
1644 "Invalid TF entry");
1646 }
else if (
SUSP_SIG(sue,
'N',
'M')) {
1650 if (name != NULL && namecont == 0) {
1653 "New NM entry found without previous"
1654 "CONTINUE flag. Ignored");
1662 "Invalid NM entry");
1665 if (name != NULL)
if (strlen(name) > 4095) {
1668 "Totally oversized NM list");
1673 #ifdef Libisofs_syslinux_tesT
1675 if (name != NULL && !namecont) {
1676 struct device syslinux_dev;
1677 struct iso_sb_info syslinux_sbi;
1678 struct fs_info syslinux_fsi;
1679 char *syslinux_name = NULL;
1680 int syslinux_name_len;
1682 syslinux_dev.src = fsdata->src;
1683 memset(&(syslinux_sbi.root), 0, 256);
1684 syslinux_sbi.do_rr = 1;
1685 syslinux_sbi.susp_skip = 0;
1686 syslinux_fsi.fs_dev = &syslinux_dev;
1687 syslinux_fsi.fs_info = &syslinux_sbi;
1688 ret = susp_rr_get_nm(&syslinux_fsi, (
char *) record,
1689 &syslinux_name, &syslinux_name_len);
1691 if (name == NULL || syslinux_name == NULL)
1692 fprintf(stderr,
"################ Hoppla. NULL\n");
1693 else if(strcmp(syslinux_name, name) != 0)
1695 "################ libisofs '%s' != '%s' susp_rr_get_nm()\n",
1696 name, syslinux_name);
1697 }
else if (ret == 0) {
1699 "################ '%s' not found by susp_rr_get_nm()\n", name);
1701 fprintf(stderr,
"################ 'susp_rr_get_nm() returned error\n");
1703 if (syslinux_name != NULL)
1704 free(syslinux_name);
1711 }
else if (
SUSP_SIG(sue,
'S',
'L')) {
1712 if (linkdest != NULL && linkdestcont == 0) {
1715 "New SL entry found without previous"
1716 "CONTINUE flag. Ignored");
1719 ret =
read_rr_SL(sue, &linkdest, &linkdestcont);
1723 "Invalid SL entry");
1725 }
else if (
SUSP_SIG(sue,
'R',
'E')) {
1735 "Root directory is marked by RRIP RE as relocated");
1740 }
else if (
SUSP_SIG(sue,
'C',
'L') && (flag & 2)) {
1742 "Invalid CL entry, found in CL target");
1744 }
else if (
SUSP_SIG(sue,
'C',
'L')) {
1752 if (relocated_dir == 0) {
1754 "Invalid CL entry, no child location");
1757 }
else if (
SUSP_SIG(sue,
'P',
'N')) {
1762 "Invalid PN entry");
1764 }
else if (
SUSP_SIG(sue,
'S',
'F')) {
1766 "Sparse files not supported.");
1768 }
else if (
SUSP_SIG(sue,
'R',
'R')) {
1774 }
else if (
SUSP_SIG(sue,
'S',
'P')) {
1782 "SP entry found in a directory entry other "
1783 "than '.' entry of root node");
1786 }
else if (
SUSP_SIG(sue,
'E',
'R')) {
1794 "ER entry found in a directory entry other "
1795 "than '.' entry of root node");
1802 }
else if (
SUSP_SIG(sue,
'A',
'A')) {
1805 &prev_field, &aa_done, 0);
1809 "Invalid AA entry");
1813 }
else if (
SUSP_SIG(sue,
'A',
'L')) {
1816 &prev_field, &aa_done, 0);
1820 "Invalid AL entry");
1824 #ifdef Libisofs_with_zliB
1829 &zisofs_bsl2, &zisofs_usize, 0);
1835 "Invalid ZF entry" :
1836 "Invalid Z2 entry");
1840 if (zisofs_alg[0] ==
'p' || zisofs_alg[1] ==
'z') {
1843 }
else if (zisofs_alg[0] ==
'P' || zisofs_alg[1] ==
'Z') {
1870 }
else if (!relocated_dir && atts.st_mode == (mode_t) 0 ) {
1872 "Rock Ridge PX entry is not present or it "
1873 "contains invalid values.");
1876 if (namecont != 0) {
1878 "Incomplete Rock Ridge name, last NM entry continues");
1880 if (linkdestcont != 0) {
1882 "Incomplete link destination, last SL entry continues");
1892 if (strcmp(fsdata->input_charset, fsdata->local_charset) && name) {
1894 char *newname = NULL;
1895 ret =
strconv(name, fsdata->input_charset, fsdata->local_charset,
1902 "Cannot convert from charset %.40s to %.40s",
1903 fsdata->input_charset, fsdata->local_charset);
1918 if (strcmp(fsdata->input_charset, fsdata->local_charset) && linkdest) {
1920 char *newlinkdest = NULL;
1921 ret =
strconv(linkdest, fsdata->input_charset,
1922 fsdata->local_charset, &newlinkdest);
1927 "Charset conversion error. Cannot convert from %.40s to %.40s",
1928 fsdata->input_charset, fsdata->local_charset);
1938 linkdest = newlinkdest;
1944 atts.st_gid = fsdata->gid;
1945 atts.st_uid = fsdata->uid;
1946 if (record->flags[0] & 0x02) {
1947 atts.st_mode = S_IFDIR | fsdata->dir_mode;
1949 atts.st_mode = S_IFREG | fsdata->file_mode;
1954 fsdata->px_ino_status |= 4;
1964 if (record->len_fi[0] == 1 && record->file_id[0] == 0) {
1966 if (!(atts.st_mode & S_IFDIR)) {
1968 "Wrong ISO file name. \".\" not dir");
1973 name =
get_name(fsdata, (
char*)record->file_id, record->len_fi[0]);
1976 "Cannot retrieve file name");
1982 if (fsdata->iso_root_block == fsdata->svd_root_block)
1983 ecma119_map = fsdata->joliet_map;
1985 ecma119_map = fsdata->ecma119_map;
1986 if (ecma119_map >= 1 && ecma119_map <= 3 &&
1987 len > 2 && name[len-2] ==
';' && name[len-1] ==
'1') {
1988 if (len > 3 && name[len-3] ==
'.') {
1999 if (ecma119_map == 2 || ecma119_map == 3) {
2000 for (cpt = name; *cpt != 0; cpt++) {
2001 if (ecma119_map == 2) {
2003 *cpt = toupper(*cpt);
2006 *cpt = tolower(*cpt);
2015 if ((
int) strlen(name) > fsdata->truncate_length) {
2017 fsdata->truncate_length, name, 0);
2023 if (relocated_dir) {
2032 ret = fsdata->src->read_block(fsdata->src, relocated_dir,
buffer);
2046 if (ifsdata->name != NULL)
2047 free(ifsdata->name);
2048 ifsdata->name = name;
2063 if (atts.st_atime == (time_t) 0) {
2064 atts.st_atime = recorded;
2066 if (atts.st_ctime == (time_t) 0) {
2067 atts.st_ctime = recorded;
2069 if (atts.st_mtime == (time_t) 0) {
2070 atts.st_mtime = recorded;
2074 atts.st_size =
iso_read_bb(record->length, 4, NULL);
2077 atts.st_dev = fsdata->id;
2082 if (S_ISLNK(atts.st_mode) && (linkdest == NULL)) {
2084 "Link without destination.");
2092 if (ifsdata == NULL) {
2097 if (ifsrc == NULL) {
2102 ifsdata = (*src)->data;
2104 free(ifsdata->name);
2105 ifsdata->name = NULL;
2106 atts.st_size += (off_t)ifsdata->info.st_size;
2107 if (ifsdata->aa_string != NULL)
2108 free(ifsdata->aa_string);
2109 ifsdata->aa_string = NULL;
2115 if (parent != NULL) {
2116 ifsdata->parent = parent;
2119 ifsdata->info = atts;
2120 ifsdata->name = name;
2121 ifsdata->aa_string = aa_string;
2123 #ifdef Libisofs_with_zliB
2124 if (zisofs_hs4 > 0) {
2125 ifsdata->zisofs_algo[0] = zisofs_alg[0];
2126 ifsdata->zisofs_algo[1] = zisofs_alg[1];
2127 ifsdata->header_size_div4 = zisofs_hs4;
2128 ifsdata->block_size_log2 = zisofs_bsl2;
2129 ifsdata->uncompressed_size = zisofs_usize;
2131 ifsdata->header_size_div4 = 0;
2136 ifsdata->sections = realloc(ifsdata->sections,
2138 if (ifsdata->sections == NULL) {
2139 free(ifsdata->name);
2143 ifsdata->sections[ifsdata->nsections].block =
2144 iso_read_bb(record->block, 4, NULL) + record->len_xa[0];
2145 ifsdata->sections[ifsdata->nsections].size =
iso_read_bb(record->length, 4, NULL);
2146 ifsdata->nsections++;
2148 if (S_ISLNK(atts.st_mode)) {
2149 ifsdata->data.content = linkdest;
2150 }
else if (linkdest != NULL) {
2152 "RRIP SL link destination with file that is not a link.");
2158 ifsrc->data = ifsdata;
2159 ifsrc->refcount = 1;
2183 if (fs == NULL || fs->
data == NULL || root == NULL) {
2234 if (!strcmp(name, fname)) {
2252 char *ptr, *brk_info, *component;
2254 if (fs == NULL || fs->
data == NULL || path == NULL || file == NULL) {
2258 if (path[0] !=
'/') {
2273 if (!strcmp(path,
"/")) {
2287 component = strtok_r(ptr,
"/", &brk_info);
2293 if (!S_ISDIR(fdata->
info.st_mode)) {
2306 component = strtok_r(NULL,
"/", &brk_info);
2313 }
else if (ret == 0) {
2334 if (fs == NULL || fs->
data == NULL) {
2356 if (fs == NULL || fs->
data == NULL) {
2418 unsigned char *
buffer = NULL;
2432 #ifdef Libisofs_syslinux_tesT
2435 struct device syslinux_dev;
2436 struct iso_sb_info syslinux_sbi;
2437 struct fs_info syslinux_fsi;
2439 syslinux_dev.src = data->
src;
2440 memcpy(&(syslinux_sbi.root), (
char *) record, 256);
2441 syslinux_sbi.do_rr = 1;
2442 syslinux_sbi.susp_skip = 0;
2443 syslinux_fsi.fs_dev = &syslinux_dev;
2444 syslinux_fsi.fs_info = &syslinux_sbi;
2446 ret = susp_rr_check_signatures(&syslinux_fsi, 1);
2447 fprintf(stderr,
"--------- susp_rr_check_signatures == %d , syslinux_sbi.do_rr == %d\n", ret, syslinux_sbi.do_rr);
2472 }
else if (ret == 0 || !
SUSP_SIG(sue,
'S',
'P') ) {
2484 "SUSP SP system use entry seems to be wrong. "
2485 "Ignoring Rock Ridge Extensions.");
2523 !strncmp((
char*)sue->
data.
ER.
ext_id,
"RRIP_1991A", 10) ) {
2526 "Suitable Rock Ridge ER found. Version 1.10.");
2530 !strncmp((
char*)sue->
data.
ER.
ext_id,
"IEEE_P1282", 10))
2532 !strncmp((
char*)sue->
data.
ER.
ext_id,
"IEEE_1282", 9)) ) {
2535 "Suitable Rock Ridge ER found. Version 1.12.");
2539 (strncmp((
char*)sue->
data.
ER.
ext_id,
"AAIP_0002", 9) == 0 ||
2540 strncmp((
char*)sue->
data.
ER.
ext_id,
"AAIP_0100", 9) == 0 ||
2541 strncmp((
char*)sue->
data.
ER.
ext_id,
"AAIP_0200", 9) == 0)) {
2546 if (strncmp((
char*)sue->
data.
ER.
ext_id,
"AAIP_0200", 9) == 0)
2554 "Identifier for extension AAIP found, but loading is not enabled.");
2558 "Unknown Extension Signature found in ER.\n"
2559 "It will be ignored, but can cause problems in "
2560 "image reading. Please notify us about this.");
2582 uint32_t *image_size)
2599 if (image_size != NULL)
2688 int ret, i, rx, last_done, idx, bufsize;
2692 unsigned char *
buffer = NULL, *rpt;
2708 "Wrong or damaged El-Torito Catalog. El-Torito info "
2709 "will be ignored.");
2736 for (rx = 64; (
buffer[rx] & 0xfe) == 0x90 && !last_done; rx += 32) {
2737 last_done =
buffer[rx] & 1;
2755 "Too many boot images found. List truncated.");
2756 goto after_bootblocks;
2789 for(rx = 0; rx < bufsize; rx +=
BLOCK_SIZE) {
2790 rpt = (
unsigned char *) (data->
catcontent + rx);
2813 char *
block = NULL, md5[16];
2814 int desired = (1 << 2);
2816 uint32_t next_tag = 0, i;
2823 desired |= (1 << 4);
2824 for (i = 0; i < 32; i++) {
2831 ctx, start_lba, &tag_type, &next_tag, 0);
2849 if (tag_type == 4) {
2851 if (next_tag < 32) {
2863 for (i++; start_lba + i <= next_tag; i++) {
2867 if (start_lba + i < next_tag)
2871 ctx, start_lba, &tag_type, &next_tag, 0);
2896 if (src == NULL || opts == NULL || fs == NULL) {
2928 data->
msgid = msgid;
2930 if (opts->
nomd5 == 0)
2932 else if (opts->
nomd5 == 2)
2956 memcpy(ifs->
type,
"iso ", 4);
2973 "Image loading aborted due to MD5 mismatch of image tree data",
2976 "You may override this refusal by disabling MD5 checking",
3010 "EL TORITO SPECIFICATION", 23)) {
3013 "Unsupported Boot Vol. Desc. Only El-Torito "
3014 "Specification, Version 1.0 Volume "
3015 "Descriptors are supported. Ignoring boot info");
3060 "Unsupported Sup. Vol. Desc found.");
3075 "Ignoring Volume descriptor %x.",
buffer[0]);
3079 }
while (
buffer[0] != 255);
3164 unsigned char *aa_string;
3167 char *a_text = NULL, *d_text = NULL;
3174 if (ret != 1 || aa_string == NULL)
3200 int ret, idx, to_copy;
3209 #ifdef Libisofs_with_zliB
3212 uint8_t header_size_div4, uint8_t block_size_log2,
3213 uint64_t uncompressed_size,
int flag);
3217 if (builder == NULL || src == NULL || node == NULL || src->
data == NULL) {
3224 if (in_name == NULL) {
3227 name = strdup(in_name);
3239 switch (info.st_mode & S_IFMT) {
3249 "More than one catalog node has been found. "
3250 "We can continue, but that could lead to "
3259 new = calloc(1,
sizeof(
IsoBoot));
3265 bootcat->
size = info.st_size;
3269 if (bootcat->
size > 0) {
3271 if (bootcat->
content == NULL) {
3274 to_copy = bootcat->
size;
3295 file = calloc(1,
sizeof(
IsoFile));
3324 #ifdef Libisofs_with_zliB
3326 if (data->header_size_div4 > 0) {
3328 data->header_size_div4,
3329 data->block_size_log2,
3330 data->uncompressed_size, 0);
3350 if (idx < fsdata->num_bootimgs) {
3364 "More than one ISO node has been found for the same boot image.");
3381 new = calloc(1,
sizeof(
IsoDir));
3404 link->
dest = strdup(dest);
3407 link->
st_dev = info.st_dev;
3408 link->
st_ino = info.st_ino;
3421 if (special == NULL) {
3424 special->
dev = info.st_rdev;
3427 special->
st_dev = info.st_dev;
3428 special->
st_ino = info.st_ino;
3438 new->name = name; name = NULL;
3439 new->mode = info.st_mode;
3440 new->uid = info.st_uid;
3441 new->gid = info.st_gid;
3442 new->atime = info.st_atime;
3443 new->mtime = info.st_mtime;
3444 new->ctime = info.st_ctime;
3457 if (info.st_ino != 0 && (info.st_mode & S_IFMT) != S_IFREG &&
3464 *node =
new;
new = NULL;
3485 if (builder == NULL) {
3519 if (fs == NULL || fs->
data == NULL || src == NULL) {
3525 memset(&atts, 0,
sizeof(
struct stat));
3526 atts.st_mode = S_IFREG;
3539 atts.st_dev = fsdata->id;
3545 if (ifsdata == NULL) {
3547 goto boot_fs_cleanup;
3550 if (ifsrc == NULL) {
3552 goto boot_fs_cleanup;
3558 goto boot_fs_cleanup;
3565 ifsdata->
info = atts;
3566 ifsdata->
name = NULL;
3572 ifsrc->
data = ifsdata;
3585 #define Libisofs_boot_image_max_sizE (4096*1024)
3594 int i, j, ret, section_count, todo, chunk;
3595 uint32_t img_lba, img_size, boot_pvd_found, image_pvd, alleged_size;
3598 uint8_t *boot_image_buf = NULL, boot_info_found[16], *buf = NULL;
3603 if (
image->bootcat == NULL)
3606 for (i = 0; i <
image->bootcat->num_bootimages; i++) {
3607 boot =
image->bootcat->bootimages[i];
3608 boot_file = boot->
image;
3618 §ion_count, §ions, 0);
3619 if (ret == 1 && section_count > 0)
3620 img_lba = sections[0].
block;
3621 if (sections != NULL) {
3628 boot_image_buf = calloc(1, img_size);
3629 if (boot_image_buf == NULL) {
3639 for (todo = img_size; todo > 0; ) {
3655 memcpy(boot_info_found, boot_image_buf + 8, 16);
3657 image_pvd = (uint32_t) (opts->
block + 16);
3660 if (image_pvd != boot_pvd_found &&
3661 image_pvd == 16 && boot_pvd_found < iso_image_size) {
3667 alleged_size + boot_pvd_found == iso_image_size + image_pvd)
3668 image_pvd = boot_pvd_found;
3675 if (memcmp(boot_image_buf + 8, boot_info_found, 16) == 0)
3682 blk = (blk << 8) | boot_image_buf[j];
3687 if (boot_image_buf[64] == 0xfb && boot_image_buf[65] == 0xc0 &&
3688 boot_image_buf[66] == 0x78 && boot_image_buf[67] == 0x70)
3691 free(boot_image_buf);
3692 boot_image_buf = NULL;
3696 if (boot_image_buf != NULL)
3697 free(boot_image_buf);
3710 "More file name collisions had to be resolved");
3714 "Sum of resolved file name collisions: %.f",
3735 if (lba == ((uint32_t) s) - 1 && c == 0 && h == 0)
3737 if (c == 1023 && h >= 254 && s == 63)
3743 for (i = 1; i <= 255; i++) {
3744 for (j = 1; j <= 63; j++) {
3745 res = ((c * i) + h) * j + (s - 1);
3747 matches[(i / 8) * 32 + (j - 1)] &= ~(1 << (i % 8));
3764 int *hc,
int *sh,
int flag)
3767 static int pref[][2] = {{64, 32}, {255, 63}}, prefs = 2;
3775 for (k = 0; k < prefs; k++) {
3778 if ((uint32_t) (1024 / 4 * i * j) <= iso_image_size)
3780 if (matches[(i / 8) * 32 + (j - 1)] & (1 << (i % 8))) {
3788 for (i = 1; i <= 255; i++) {
3789 for (j = 1; j <= 63; j++) {
3790 if ((uint32_t) (1024 / 4 * i * j) <= iso_image_size)
3792 if (matches[(i / 8) * 32 + (j - 1)] & (1 << (i % 8))) {
3793 if( i * j < *hc * *sh)
3805 int i, j, ret, cyl_align_mode, part_after_image = 0;
3806 uint32_t start_h, start_s, start_c, end_h, end_s, end_c, sph = 0, hpc = 0;
3807 uint32_t start_lba, num_blocks, end_chs_lba, image_size, lba, cyl_size;
3808 uint8_t *data, pstatus, ptype, *hc_sh = NULL;
3813 memset(hc_sh, 0xff, 32 * 63);
3817 for (i = 0; i < 4; i++) {
3819 for (j = 0; j < 16; j++)
3826 start_c = ((data[2] & 0xc0) << 2) | data[3];
3828 start_s = data[2] & 63;
3829 end_c = ((data[6] & 0xc0) << 2) | data[7];
3831 end_s = data[6] & 63;
3834 if (num_blocks <= 0)
3839 }
else if (sph == 0) {
3843 if (end_h + 1 != hpc)
3845 }
else if (hpc == 0) {
3849 end_chs_lba = ((end_c * hpc) + end_h) * sph + end_s;
3850 if (hpc > 0 && hpc < 0xffffffff && sph > 0 && sph < 0xffffffff)
3851 if (end_chs_lba != start_lba + num_blocks)
3852 hpc = sph = 0xffffffff;
3855 iso_scan_hc_sh(start_lba + num_blocks - 1, end_c, end_h, end_s, hc_sh);
3865 (uint64_t) start_lba, (uint64_t) num_blocks,
3866 ptype, pstatus, i + 1);
3869 if ((start_lba + num_blocks + 3) / 4 >
image_size)
3870 image_size = (start_lba + num_blocks + 3) / 4;
3873 if (hpc > 0 && hpc < 0xffffffff && sph > 0 && sph < 0xffffffff) {
3891 part_after_image = 1;
3892 end_c = lba / cyl_size;
3893 if (end_c * cyl_size != lba)
3918 uint32_t eltorito_lba = 0;
3920 int i, section_count, ret;
3938 if (ret > 0 && section_count > 0)
3939 eltorito_lba = sections[0].
block;
3945 for (i= 0; i < 426; i++)
3946 if(strncmp((
char *) (sad + i),
"isolinux", 8) == 0)
3951 if (mbr_lba == eltorito_lba)
3959 if (mbr_lba / 4 - 1 == eltorito_lba)
3967 uint64_t start_block, uint64_t block_count,
3971 uint8_t *buf = NULL;
3981 p_offset = start_block / 4;
3982 ret = src->
read_block(src, p_offset + 16, buf);
3991 iso_size == block_count / 4))
4004 int sub_type = 2, ret, is_isohybrid = 0, is_grub2_mbr = 0;
4005 int is_protective_label = 0;
4006 uint64_t part2_start;
4015 if (((
unsigned char *) sad)[510] != 0x55 ||
4016 ((
unsigned char *) sad)[511] != 0xaa)
4029 }
else if(ret == 2) {
4073 is_protective_label = 1;
4112 is_protective_label |
4113 (is_isohybrid << 1) |
4115 (is_grub2_mbr << 14);
4124 uint32_t head_size, entry_size;
4126 if (strncmp((
char *) head,
"EFI PART", 8) != 0)
4128 if (head[8] || head[9] || head[10] != 1 || head[11])
4134 if (entry_size != 128)
4143 uint64_t part_start;
4144 uint32_t iso_block, found_crc, crc, entry_count, array_crc;
4145 uint8_t *head, *part_array, *b_part, *m_part;
4146 int ret, i, num_iso_blocks, l, j, entries_diff;
4147 unsigned char *buf = NULL;
4148 char *comments = NULL;
4159 sprintf(comments + strlen(comments),
"Implausible header LBA %.f, ",
4164 sprintf(comments + strlen(comments),
4165 "Cannot read header block at 2k LBA %.f, ",
4166 (
double) iso_block);
4173 "Not a GPT 1.0 header of 92 bytes for 128 bytes per entry, ");
4180 memset(head + 16, 0, 4);
4182 if (found_crc != crc) {
4183 sprintf(comments + strlen(comments),
4184 "Head CRC 0x%8x wrong. Should be 0x%8x",
4187 if (found_crc == crc) {
4188 strcat(comments,
". Matches all 512 block bytes, ");
4190 strcat(comments,
", ");
4194 for (i = 0; i < 16; i ++)
4198 sprintf(comments + strlen(comments),
"Disk GUID differs (");
4200 sprintf(comments + strlen(comments),
"), ");
4211 sprintf(comments + strlen(comments),
4212 "Number of array entries %u differs from main GPT %u, ",
4217 sprintf(comments + strlen(comments),
"Implausible array LBA %.f, ",
4218 (
double) part_start);
4219 iso_block = part_start / 4;
4220 num_iso_blocks = (part_start + (entry_count + 3) / 4) / 4 - iso_block + 1;
4221 for (i = 0; i < num_iso_blocks; i++) {
4222 ret = src->
read_block(src, iso_block + (uint32_t) i, buf + i * 2048);
4224 sprintf(comments + strlen(comments),
4225 "Cannot read array block at 2k LBA %.f, ",
4226 (
double) iso_block);
4230 part_array = buf + (part_start % 4) * 512;
4232 crc =
iso_crc32_gpt((
unsigned char *) part_array, 128 * entry_count, 0);
4233 if (crc != array_crc)
4234 sprintf(comments + strlen(comments),
4235 "Array CRC 0x%8x wrong. Should be 0x%8x, ", array_crc, crc);
4239 for (i = 0; i < (int) entry_count; i++) {
4240 b_part = part_array + 128 * i;
4243 for (j = 0; j < 128; j++)
4244 if (b_part[j] != m_part[j])
4247 if (!entries_diff) {
4248 strcat(comments,
"Entries differ for partitions");
4251 sprintf(comments + strlen(comments),
" %d", i + 1);
4255 strcat(comments,
", ");
4261 if (comments != NULL) {
4262 l = strlen(comments);
4264 if (comments[l - 2] ==
',' && comments[l - 1] ==
' ')
4265 comments[l - 2] = 0;
4281 uint64_t part_start;
4283 unsigned char *crc_buf = NULL;
4293 memcpy(crc_buf, head, 512);
4294 memset(crc_buf + 16, 0, 4);
4336 uint64_t start_block, block_count, flags, end_block, j_end, j_start;
4349 for (j = 0; j < 128; j++)
4357 if ((start_block == 0 && block_count == 0) ||
4358 block_count + 1 < start_block)
4360 block_count = block_count + 1 - start_block;
4368 start_block, block_count,
4369 part, part + 16, flags, part + 56);
4391 if ((start_block <= j_start && j_start < end_block) ||
4392 (start_block <= j_end && j_end < end_block) ||
4393 (j_start <= start_block && start_block < j_end)) {
4407 if (start_block >= 64 && block_count >= 72 &&
4408 start_block <= 2048 && start_block % 4 == 0 &&
4409 block_count % 4 == 0) {
4428 uint32_t block_size;
4433 if (sad[0] !=
'E' || sad[1] !=
'R')
4436 if (block_size != 2048 && block_size != 512)
4448 uint32_t map_entries, start_block, block_count, flags;
4449 char *sad, *part, name[33], type_string[33];
4461 for (i = 0; i < (int) map_entries; i++) {
4463 if (part[0] !=
'P' || part[1] !=
'M')
4468 memcpy(type_string, part + 48, 32);
4469 type_string[32] = 0;
4470 if(strcmp(type_string,
"Apple_partition_map") == 0)
4473 block_count =
iso_read_msb(((uint8_t *) part + 12), 4);
4474 memcpy(name, part + 16, 32);
4483 start_block, block_count, name, type_string);
4486 if (strncmp(name,
"Gap", 3) == 0 &&
4487 strcmp(type_string,
"ISO9660_data") == 0) {
4488 if (
'0' <= name[3] && name[3] <=
'9' && (name[4] == 0 ||
4489 (
'0' <= name[4] && name[4] <=
'9' && name[5] == 0))) {
4501 int ret = 0, spt, bps, i, j, idx;
4502 uint32_t magic, chk, head_chk;
4504 uint8_t *usad, *upart;
4510 usad = (uint8_t *) sad;
4513 if (magic != 0x0be5a941)
4517 if (spt != 32 || bps != 512)
4520 for (i = 0; i < 504; i += 4)
4523 if (chk != head_chk)
4527 for (j = 312; j < 408; j++)
4533 for (i = 0; i < 15; i++) {
4534 upart = usad + 72 + 16 * i;
4535 for (j = 0; j < 16; j++)
4548 for (j = 0; j < 15; j++) {
4582 int ret = 0, i, section_count;
4593 usad = (uint8_t *) sad;
4595 for (i = 0; i < 8; i++)
4599 if (magic != 0x0002757a)
4613 if (ret > 0 && section_count > 0) {
4614 if (sections[0].
block < (1 << 30) &&
4617 sections[0].
block * 4;
4630 int ret = 0, i, idx;
4632 uint8_t *usad, checksum[2];
4634 uint64_t last_core_block;
4640 usad = (uint8_t *) sad;
4655 checksum[0] = checksum[1] = 0;
4656 for (i = 0; i < 510; i += 2) {
4657 checksum[0] ^= usad[i];
4658 checksum[1] ^= usad[i + 1];
4660 if (checksum[0] != usad[510] || checksum[1] != usad[511])
4671 for (i = 0; i < 8; i++) {
4697 if (last_core_block > 0)
4699 if (last_core_block > 17 && last_core_block < sai->
image_size) {
4701 (uint32_t) last_core_block, &node,
4721 int ret = 0, i, cmd_adr, cmd_len;
4722 char *sad, *paths[4];
4731 usad = (uint8_t *) sad;
4734 if (magic != 0x8000 || strncmp(sad + 2,
"PALO", 5) != 0 ||
4735 sad[7] < 4 || sad[7] > 5)
4759 for (i = 0; i < 4; i++) {
4783 int ret = 0, i, section_count;
4789 uint64_t checksum_found, checksum_should = 0, size;
4794 usad = (uint8_t *) sad;
4797 for (i = 0; i < 63; i++)
4799 if (checksum_found != checksum_should)
4813 if (ret > 0 && section_count > 0) {
4814 size = sections[0].
size / 512 + !!(sections[0].
size % 512);
4820 }
else if (strncmp(sad,
"Linux/Alpha aboot for ISO filesystem.", 37) != 0
4858 if ((*r)->buf != NULL)
4860 if ((*r)->lines != NULL)
4869 if (target->
buf != NULL)
4871 if (target->
lines != NULL)
4879 char *msg,
char *path,
int flag)
4882 sprintf(msg + strlen(msg),
"(too long to show here)");
4891 if ((*na == 0 || *na > claim) && block < claim)
4897 uint32_t *next_above,
int flag)
4899 int i, section_count, ret;
4942 if (ret > 0 && section_count > 0)
4946 if (sections != NULL) {
4963 uint32_t start_block,
int flag)
4966 char *path = NULL, *cpt;
4968 uint32_t next_above = 0;
4972 &node, &next_above, 0);
4982 if (next_above == 0)
4984 size = next_above - start_block;
4987 cpt = strstr(msg,
"path");
4994 memcpy(path + (cpt - msg),
"blks", 4);
4995 sprintf(path + strlen(path),
"%u", (
unsigned int)
size);
5011 char *msg = NULL, *local_name = NULL, *path;
5012 int i, j, sa_type, sao, sa_sub, ret, idx;
5018 static char *alignments[4] = {
"auto",
"on",
"off",
"all"};
5031 sprintf(msg,
"System area options: 0x%-8.8x", (
unsigned int) sao);
5035 sa_type = (sao >> 2) & 63;
5036 sa_sub = (sao >> 10) & 15;
5037 strcpy(msg,
"System area summary:");
5039 if ((sao & 3) || sa_sub == 1 || sa_sub == 2) {
5040 strcat(msg,
" MBR");
5042 strcat(msg,
" isohybrid");
5044 strcat(msg,
" protective-msdos-label");
5045 else if (sa_sub == 1) {
5046 strcat(msg,
" CHRP");
5048 if ((sao & (1 << 14)) && !(sao & 2))
5049 strcat(msg,
" grub2-mbr");
5050 sprintf(msg + strlen(msg),
" cyl-align-%s",
5051 alignments[(sao >> 8) & 3]);
5053 strcat(msg,
" PReP");
5055 strcat(msg,
" MBR");
5057 strcat(msg,
" not-recognized");
5059 }
else if (sa_type == 1) {
5060 strcat(msg,
" MIPS-Big-Endian");
5061 }
else if (sa_type == 2) {
5062 strcat(msg,
" MIPS-Little-Endian");
5063 }
else if (sa_type == 3) {
5064 strcat(msg,
" SUN-SPARC-Disk-Label");
5065 }
else if (sa_type == 4 || sa_type == 5) {
5066 sprintf(msg + strlen(msg),
" HP-PA-PALO");
5067 }
else if (sa_type == 6) {
5068 sprintf(msg + strlen(msg),
" DEC-Alpha");
5070 sprintf(msg + strlen(msg),
" unkown-system-area-type-%d", sa_type);
5073 strcat(msg,
" GPT");
5075 strcat(msg,
" APM");
5079 sprintf(msg,
"ISO image size/512 : %.f",
5086 if (sa_type >= 4 && sa_type <= 5) {
5089 sprintf(msg,
"HP-PA cmdline : ");
5091 sprintf(msg,
"HP-PA boot files : ByteAddr ByteSize Path");
5093 sprintf(msg,
"HP-PA 32-bit kernel: %10u %10u ",
5098 sprintf(msg,
"HP-PA 64-bit kernel: %10u %10u ",
5103 sprintf(msg,
"HP-PA ramdisk : %10u %10u ",
5108 sprintf(msg,
"HP-PA bootloader : %10u %10u ",
5113 }
else if (sa_type == 6) {
5114 sprintf(msg,
"DEC Alpha ldr size : %.f",
5117 sprintf(msg,
"DEC Alpha ldr adr : %.f",
5131 "MBR partition table: N Status Type Start Blocks");
5137 "MBR partition : %3d 0x%2.2x 0x%2.2x %11.f %11.f",
5148 sprintf(msg,
"MBR partition path : %3d ", part->
desired_slot);
5153 sprintf(msg,
"PReP boot partition: %u %u",
5160 "MIPS-BE volume dir : N Name Block Bytes");
5164 "MIPS-BE boot entry : %3d %8s %10u %10u",
5170 sprintf(msg,
"MIPS-BE boot path : %3d ", i + 1);
5175 }
else if (sa_type == 2) {
5177 "MIPS-LE boot map : LoadAddr ExecAddr SegmentSize SegmentStart");
5179 sprintf(msg,
"MIPS-LE boot params: %10u %10u %10u %10u",
5184 sprintf(msg,
"MIPS-LE boot path : ");
5190 }
else if (sa_type == 3) {
5198 "SUN SPARC partmap : N IdTag Perms StartCyl NumBlocks");
5203 "SUN SPARC partition: %3d 0x%4.4x 0x%4.4x %10u %10u",
5210 sprintf(msg,
"SPARC GRUB2 core : %.f %u",
5217 sprintf(msg,
"SPARC GRUB2 path : ");
5226 sprintf(msg,
"GPT : N Info");
5230 "GPT CRC should be : 0x%8.8x to match first 92 GPT header block bytes",
5234 "GPT CRC found : 0x%8.8x matches all 512 bytes of GPT header block",
5240 "GPT array CRC wrong: should be 0x%8.8x , found 0x%8.8x",
5246 sprintf(msg,
"GPT backup problems: ");
5251 sprintf(msg,
"GPT disk GUID : ");
5254 sprintf(msg,
"GPT entry array : %u %u %s",
5259 sprintf(msg,
"GPT lba range : %.f %.f %.f",
5274 sprintf(msg,
"GPT partition name : %3d ",
idx);
5275 for (j = 72; j >= 2; j -= 2)
5276 if (gpt_entry->
name[j - 2] || gpt_entry->
name[j - 1])
5282 &local_name, &local_len, 0 | 512 | (1 << 15));
5285 if (ret == 1 && local_len <= 228) {
5286 sprintf(msg,
"GPT partname local : %3d ",
idx);
5287 memcpy(msg + 26, local_name, local_len);
5289 msg[26 + local_len] = 0;
5292 sprintf(msg,
"GPT partition GUID : %3d ",
idx);
5295 sprintf(msg,
"GPT type GUID : %3d ",
idx);
5298 sprintf(msg,
"GPT partition flags: %3d 0x%8.8x%8.8x",
idx,
5299 (
unsigned int) ((gpt_entry->
flags >> 32) & 0xffffffff),
5300 (
unsigned int) (gpt_entry->
flags & 0xffffffff));
5302 sprintf(msg,
"GPT start and size : %3d %.f %.f",
idx,
5308 sprintf(msg,
"GPT partition path : %3d ",
idx);
5314 sprintf(msg,
"APM : N Info");
5324 sprintf(msg,
"APM partition name : %3d %s",
idx, apm_entry->
name);
5326 sprintf(msg,
"APM partition type : %3d %s",
idx, apm_entry->
type);
5328 sprintf(msg,
"APM start and size : %3d %.f %.f",
idx,
5334 sprintf(msg,
"APM partition path : %3d ",
idx);
5353 if (*result == NULL)
5355 if ((*result)[0] != NULL)
5369 for (i = 0; strcmp(doc[i],
"@END_OF_DOC@") != 0; i++)
5370 count += strlen(doc[i]) + 1;
5373 *result = calloc(i,
sizeof(
char *));
5374 if (*result == NULL)
5376 buf = calloc(1, count);
5384 for (i = 0; strcmp(doc[i],
"@END_OF_DOC@") != 0; i++) {
5385 strcpy(buf + count, doc[i]);
5386 (*result)[i] = buf + count;
5387 count += strlen(doc[i]) + 1;
5394 uint32_t lba,
int flag)
5396 uint32_t max_size = 0, start_lba,
num_blocks;
5410 for (i = 0; i < 4; i++) {
5425 char *msg = NULL, emul_code[6], pltf[5], *path;
5426 int i, j, ret, section_count;
5427 uint32_t lba, *lba_mem = NULL;
5432 static char emul_names[5][6] = {
"none",
"fd1.2",
"fd1.4",
"fd2.8",
"hd"};
5433 static char pltf_names[3][5] = {
"BIOS",
"PPC",
"Mac"};
5434 static int num_emuls = 5, num_pltf = 3;
5440 if (bootcat == NULL)
5443 if (bootnode == NULL)
5446 sprintf(msg,
"El Torito catalog : %u %u",
5447 (
unsigned int) bootnode->
lba,
5448 (
unsigned int) (bootnode->
size + 2047) / 2048);
5452 sprintf(msg,
"El Torito cat path : ");
5458 "El Torito images : N Pltf B Emul Ld_seg Hdpt Ldsiz LBA");
5464 if (img->
type < num_emuls)
5465 strcpy(emul_code, emul_names[img->
type]);
5467 sprintf(emul_code,
"0x%2.2x", (
unsigned int) img->
type);
5471 strcpy(pltf,
"UEFI");
5473 sprintf(pltf,
"0x%2.2x", (
unsigned int) img->
platform_id);
5477 if (ret > 0 && section_count > 0)
5478 lba = sections[0].
block;
5480 if (sections != NULL) {
5485 "El Torito boot img : %3d %4s %c %5s 0x%4.4x 0x%2.2x %5u %10u",
5486 i + 1, pltf, img->
bootable ?
'y' :
'n', emul_code,
5489 (
unsigned int) lba);
5494 if (lba_mem[i] != 0xffffffff) {
5495 sprintf(msg,
"El Torito img path : %3d ", i + 1);
5498 sprintf(msg,
"El Torito hdsiz/512: %3d %u",
5503 sprintf(msg,
"El Torito img opts : %3d ", i + 1);
5505 strcat(msg,
"boot-info-table ");
5507 strcat(msg,
"isohybrid-suitable ");
5509 strcat(msg,
"grub2-boot-info ");
5510 if (strlen(msg) > 27) {
5511 msg[strlen(msg) - 1] = 0;
5514 for (j = 0; j < (int)
sizeof(img->
id_string); j++)
5518 sprintf(msg,
"El Torito id string: %3d ", i + 1);
5526 sprintf(msg,
"El Torito sel crit : %3d ", i + 1);
5546 char ***result,
int *line_count,
int flag)
5564 if (flag & (1 << 15))
5587 if (target->
buf == NULL || target->
lines == NULL)
5600 *result = target->
lines;
5601 target->
lines = NULL;
5639 if (
buffer[0] != 1 || strncmp((
char *)
buffer + 1,
"CD001", 5) != 0)
5693 int ret, i, sao, sa_type, sa_sub;
5700 for (i = 0; i < 32768; i++)
5719 sa_type = (sao >> 2) & 0x3f;
5720 sa_sub = (sao >> 10) & 0xf;
5721 if (sa_type == 0 && !((sao & 3) || sa_sub == 1 || sa_sub == 2)) {