Virtual ISO: More filename calculation delegation to save more memory
This commit is contained in:
@@ -80,17 +80,16 @@ enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _viso_entry_ {
|
typedef struct _viso_entry_ {
|
||||||
char name_short[13];
|
|
||||||
union { /* save some memory */
|
union { /* save some memory */
|
||||||
uint64_t pt_offsets[4];
|
uint64_t pt_offsets[4];
|
||||||
FILE *file;
|
FILE *file;
|
||||||
};
|
};
|
||||||
union {
|
union {
|
||||||
|
char name_short[13];
|
||||||
uint64_t dr_offsets[2];
|
uint64_t dr_offsets[2];
|
||||||
uint64_t data_offset;
|
uint64_t data_offset;
|
||||||
};
|
};
|
||||||
uint16_t name_joliet[111], pt_idx; /* name_joliet size limited by maximum directory record size */
|
uint16_t pt_idx;
|
||||||
uint8_t name_joliet_len;
|
|
||||||
|
|
||||||
struct stat stats;
|
struct stat stats;
|
||||||
|
|
||||||
@@ -217,6 +216,7 @@ viso_convert_utf8(wchar_t *dest, const char *src, int buf_size)
|
|||||||
case '"': \
|
case '"': \
|
||||||
case '%': \
|
case '%': \
|
||||||
case '&': \
|
case '&': \
|
||||||
|
case '\'': \
|
||||||
case '(': \
|
case '(': \
|
||||||
case ')': \
|
case ')': \
|
||||||
case '+': \
|
case '+': \
|
||||||
@@ -236,13 +236,13 @@ viso_convert_utf8(wchar_t *dest, const char *src, int buf_size)
|
|||||||
case ':': \
|
case ':': \
|
||||||
case ';': \
|
case ';': \
|
||||||
case '?': \
|
case '?': \
|
||||||
case '\'': \
|
|
||||||
/* Valid for A but not for filenames or D. */ \
|
/* Valid for A but not for filenames or D. */ \
|
||||||
if ((charset < VISO_CHARSET_A) || (charset == VISO_CHARSET_FN)) \
|
if ((charset < VISO_CHARSET_A) || (charset == VISO_CHARSET_FN)) \
|
||||||
c = '_'; \
|
c = '_'; \
|
||||||
break; \
|
break; \
|
||||||
\
|
\
|
||||||
case 0x01 ... 0x1f: \
|
case 0x01 ... 0x1f: \
|
||||||
|
case '\\': \
|
||||||
/* Not valid for A, D or filenames. */ \
|
/* Not valid for A, D or filenames. */ \
|
||||||
if (charset <= VISO_CHARSET_FN) \
|
if (charset <= VISO_CHARSET_FN) \
|
||||||
c = '_'; \
|
c = '_'; \
|
||||||
@@ -261,23 +261,23 @@ VISO_WRITE_STR_FUNC(viso_write_string, uint8_t, char, )
|
|||||||
VISO_WRITE_STR_FUNC(viso_write_wstring, uint16_t, wchar_t, cpu_to_be16)
|
VISO_WRITE_STR_FUNC(viso_write_wstring, uint16_t, wchar_t, cpu_to_be16)
|
||||||
|
|
||||||
static int
|
static int
|
||||||
viso_get_short_filename(viso_entry_t *dir, char *dest, const char *src)
|
viso_fill_short_filename(char *data, const viso_entry_t *entry)
|
||||||
{
|
{
|
||||||
/* Get name and extension length. */
|
/* Get name and extension length. */
|
||||||
const char *ext_pos = strrchr(src, '.');
|
const char *ext_pos = strrchr(entry->basename, '.');
|
||||||
int name_len, ext_len;
|
int name_len, ext_len;
|
||||||
if (ext_pos) {
|
if (ext_pos) {
|
||||||
name_len = ext_pos - src;
|
name_len = ext_pos - entry->basename;
|
||||||
ext_len = strlen(ext_pos);
|
ext_len = strlen(ext_pos);
|
||||||
} else {
|
} else {
|
||||||
name_len = strlen(src);
|
name_len = strlen(entry->basename);
|
||||||
ext_len = 0;
|
ext_len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy name. */
|
/* Copy name. */
|
||||||
int name_copy_len = MIN(8, name_len);
|
int name_copy_len = MIN(8, name_len);
|
||||||
viso_write_string((uint8_t *) dest, src, name_copy_len, VISO_CHARSET_D);
|
viso_write_string((uint8_t *) data, entry->basename, name_copy_len, VISO_CHARSET_D);
|
||||||
dest[name_copy_len] = '\0';
|
data[name_copy_len] = '\0';
|
||||||
|
|
||||||
/* Copy extension to temporary buffer. */
|
/* Copy extension to temporary buffer. */
|
||||||
char ext[5] = { 0 };
|
char ext[5] = { 0 };
|
||||||
@@ -298,25 +298,25 @@ viso_get_short_filename(viso_entry_t *dir, char *dest, const char *src)
|
|||||||
int tail_len = -1;
|
int tail_len = -1;
|
||||||
if (i) {
|
if (i) {
|
||||||
tail_len = sprintf(tail, "~%d", i);
|
tail_len = sprintf(tail, "~%d", i);
|
||||||
strcpy(&dest[MIN(name_copy_len, 8 - tail_len)], tail);
|
strcpy(&data[MIN(name_copy_len, 8 - tail_len)], tail);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add extension to the filename if present. */
|
/* Add extension to the filename if present. */
|
||||||
if (ext[0])
|
if (ext[0])
|
||||||
strcat(dest, ext);
|
strcat(data, ext);
|
||||||
|
|
||||||
/* Go through files in this directory to make sure this filename is unique. */
|
/* Go through files in this directory to make sure this filename is unique. */
|
||||||
viso_entry_t *entry = dir->first_child;
|
viso_entry_t *other_entry = entry->parent->first_child;
|
||||||
while (entry) {
|
while (other_entry) {
|
||||||
/* Flag and stop if this filename was seen. */
|
/* Flag and stop if this filename was seen. */
|
||||||
if ((entry->name_short != dest) && !strcmp(dest, entry->name_short)) {
|
if ((other_entry->name_short != data) && !strcmp(data, other_entry->name_short)) {
|
||||||
tail_len = 0;
|
tail_len = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Move on to the next entry, and stop if the end of this directory was reached. */
|
/* Move on to the next entry, and stop if the end of this directory was reached. */
|
||||||
entry = entry->next;
|
other_entry = other_entry->next;
|
||||||
if (entry && (entry->parent != dir))
|
if (other_entry && (other_entry->parent != entry->parent))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -327,6 +327,63 @@ viso_get_short_filename(viso_entry_t *dir, char *dest, const char *src)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static size_t
|
||||||
|
viso_fill_fn_rr(uint8_t *data, const viso_entry_t *entry, size_t max_len)
|
||||||
|
{
|
||||||
|
/* Trim filename to max_len if needed. */
|
||||||
|
size_t len = strlen(entry->basename);
|
||||||
|
if (len > max_len) {
|
||||||
|
viso_write_string(data, entry->basename, max_len, VISO_CHARSET_FN);
|
||||||
|
|
||||||
|
/* Relocate extension if the original name exceeds the maximum length. */
|
||||||
|
if (!S_ISDIR(entry->stats.st_mode)) {
|
||||||
|
char *ext = strrchr(entry->basename, '.');
|
||||||
|
if (ext > entry->basename) {
|
||||||
|
len = strlen(ext);
|
||||||
|
if (len >= max_len)
|
||||||
|
len = max_len - 1; /* avoid creating a dotfile where there isn't one */
|
||||||
|
viso_write_string(data + (max_len - len), ext, len, VISO_CHARSET_FN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return max_len;
|
||||||
|
} else {
|
||||||
|
viso_write_string(data, entry->basename, len, VISO_CHARSET_FN);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t
|
||||||
|
viso_fill_fn_joliet(uint8_t *data, const viso_entry_t *entry, size_t max_len) /* note: receives and returns byte sizes */
|
||||||
|
{
|
||||||
|
/* Decode filename as UTF-8. */
|
||||||
|
size_t len = strlen(entry->basename);
|
||||||
|
wchar_t utf8dec[len + 1];
|
||||||
|
len = viso_convert_utf8(utf8dec, entry->basename, len + 1);
|
||||||
|
|
||||||
|
/* Trim decoded filename to max_len if needed. */
|
||||||
|
max_len /= 2;
|
||||||
|
if (len > max_len) {
|
||||||
|
viso_write_wstring((uint16_t *) data, utf8dec, max_len, VISO_CHARSET_FN);
|
||||||
|
|
||||||
|
/* Relocate extension if the original name exceeds the maximum length. */
|
||||||
|
if (!S_ISDIR(entry->stats.st_mode)) {
|
||||||
|
wchar_t *ext = wcsrchr(utf8dec, L'.');
|
||||||
|
if (ext > utf8dec) {
|
||||||
|
len = wcslen(ext);
|
||||||
|
if (len > max_len)
|
||||||
|
len = max_len;
|
||||||
|
viso_write_wstring(((uint16_t *) data) + (max_len - len), ext, len, VISO_CHARSET_FN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return max_len * 2;
|
||||||
|
} else {
|
||||||
|
viso_write_wstring((uint16_t *) data, utf8dec, len, VISO_CHARSET_FN);
|
||||||
|
return len * 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
viso_fill_time(uint8_t *data, time_t time, int longform)
|
viso_fill_time(uint8_t *data, time_t time, int longform)
|
||||||
{
|
{
|
||||||
@@ -477,31 +534,9 @@ viso_fill_dir_record(uint8_t *data, viso_entry_t *entry, int type)
|
|||||||
*r = 5; /* length */
|
*r = 5; /* length */
|
||||||
*p++ = 1; /* version */
|
*p++ = 1; /* version */
|
||||||
|
|
||||||
*p++ = 0; /* flags */
|
*p++ = 0; /* flags */
|
||||||
|
*r += viso_fill_fn_rr(p, entry, 254 - (p - data)); /* name */
|
||||||
/* Trim Rock Ridge name to fit available space. */
|
p += (*r) - 5;
|
||||||
size_t len = strlen(entry->basename),
|
|
||||||
max_len = 254 - (p - data);
|
|
||||||
if (len > max_len) {
|
|
||||||
*r += max_len;
|
|
||||||
viso_write_string(p, entry->basename, max_len, VISO_CHARSET_FN);
|
|
||||||
p += max_len;
|
|
||||||
|
|
||||||
/* Relocate extension if this is a file whose name exceeds the maximum length. */
|
|
||||||
if (!S_ISDIR(entry->stats.st_mode)) {
|
|
||||||
char *ext = strrchr(entry->basename, '.');
|
|
||||||
if (ext > entry->basename) {
|
|
||||||
len = strlen(ext);
|
|
||||||
if (len >= max_len)
|
|
||||||
len = max_len - 1; /* avoid creating a dotfile where there isn't one */
|
|
||||||
viso_write_string(p - len, ext, len, VISO_CHARSET_FN);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
*r += len;
|
|
||||||
viso_write_string(p, entry->basename, len, VISO_CHARSET_FN);
|
|
||||||
p += len;
|
|
||||||
}
|
|
||||||
pad_susp:
|
pad_susp:
|
||||||
if ((p - data) & 1) /* padding for odd SUSP section lengths */
|
if ((p - data) & 1) /* padding for odd SUSP section lengths */
|
||||||
*p++ = 0;
|
*p++ = 0;
|
||||||
@@ -510,8 +545,7 @@ pad_susp:
|
|||||||
case VISO_DIR_JOLIET:
|
case VISO_DIR_JOLIET:
|
||||||
q = p++; /* save location of the file ID length for later */
|
q = p++; /* save location of the file ID length for later */
|
||||||
|
|
||||||
*q = entry->name_joliet_len * sizeof(entry->name_joliet[0]);
|
*q = viso_fill_fn_joliet(p, entry, 254 - (p - data));
|
||||||
memcpy(p, entry->name_joliet, *q); /* file ID */
|
|
||||||
p += *q;
|
p += *q;
|
||||||
|
|
||||||
if (!((*q) & 1)) /* padding for even file ID lengths */
|
if (!((*q) & 1)) /* padding for even file ID lengths */
|
||||||
@@ -641,19 +675,16 @@ viso_init(const char *dirname, int *error)
|
|||||||
cdrom_image_viso_log("VISO: init()\n");
|
cdrom_image_viso_log("VISO: init()\n");
|
||||||
|
|
||||||
/* Initialize our data structure. */
|
/* Initialize our data structure. */
|
||||||
viso_t *viso = (viso_t *) calloc(1, sizeof(viso_t));
|
viso_t *viso = (viso_t *) calloc(1, sizeof(viso_t));
|
||||||
uint8_t *data = NULL, *p;
|
uint8_t *data = NULL, *p;
|
||||||
wchar_t *wtemp = NULL;
|
*error = 1;
|
||||||
*error = 1;
|
|
||||||
if (viso == NULL)
|
if (viso == NULL)
|
||||||
goto end;
|
goto end;
|
||||||
viso->sector_size = VISO_SECTOR_SIZE;
|
viso->sector_size = VISO_SECTOR_SIZE;
|
||||||
|
|
||||||
/* Prepare temporary data buffers. */
|
/* Prepare temporary data buffers. */
|
||||||
data = calloc(2, viso->sector_size);
|
data = calloc(2, viso->sector_size);
|
||||||
int wtemp_len = MIN(64, sizeof(viso->root_dir->name_joliet) / sizeof(viso->root_dir->name_joliet[0])) + 1;
|
if (!data)
|
||||||
wtemp = malloc(wtemp_len * sizeof(wchar_t));
|
|
||||||
if (!data || !wtemp)
|
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
/* Open temporary file. */
|
/* Open temporary file. */
|
||||||
@@ -670,7 +701,7 @@ viso_init(const char *dirname, int *error)
|
|||||||
cdrom_image_viso_log("VISO: Traversing directories:\n");
|
cdrom_image_viso_log("VISO: Traversing directories:\n");
|
||||||
viso_entry_t *dir, *last_dir, *last_entry;
|
viso_entry_t *dir, *last_dir, *last_entry;
|
||||||
struct dirent *readdir_entry;
|
struct dirent *readdir_entry;
|
||||||
int max_len, len, name_len;
|
int len, name_len;
|
||||||
size_t dir_path_len;
|
size_t dir_path_len;
|
||||||
|
|
||||||
/* Fill root directory entry. */
|
/* Fill root directory entry. */
|
||||||
@@ -706,11 +737,10 @@ viso_init(const char *dirname, int *error)
|
|||||||
/* Stat the current directory or parent directory. */
|
/* Stat the current directory or parent directory. */
|
||||||
stat(i ? dir->parent->path : dir->path, &last_entry->stats);
|
stat(i ? dir->parent->path : dir->path, &last_entry->stats);
|
||||||
|
|
||||||
/* Set short and long filenames. */
|
/* Set basename. */
|
||||||
strcpy(last_entry->name_short, i ? ".." : ".");
|
strcpy(last_entry->name_short, i ? ".." : ".");
|
||||||
wcscpy(last_entry->name_joliet, i ? L".." : L".");
|
|
||||||
|
|
||||||
cdrom_image_viso_log("[%08X] %s => %s\n", last_entry, dir->path, last_entry->name_short);
|
cdrom_image_viso_log("[%08X] %s => %s\n", last_entry, dir->path, last_entry->basename);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Iterate through this directory's children. */
|
/* Iterate through this directory's children. */
|
||||||
@@ -754,31 +784,9 @@ viso_init(const char *dirname, int *error)
|
|||||||
viso->eltorito_entry = last_entry;
|
viso->eltorito_entry = last_entry;
|
||||||
|
|
||||||
/* Set short filename. */
|
/* Set short filename. */
|
||||||
if (viso_get_short_filename(dir, last_entry->name_short, readdir_entry->d_name))
|
if (viso_fill_short_filename(last_entry->name_short, last_entry))
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
/* Set Joliet long filename. */
|
|
||||||
if (wtemp_len < (name_len + 1)) { /* grow wchar buffer if needed */
|
|
||||||
wtemp_len = name_len + 1;
|
|
||||||
wtemp = realloc(wtemp, wtemp_len * sizeof(wchar_t));
|
|
||||||
}
|
|
||||||
max_len = (sizeof(last_entry->name_joliet) / sizeof(last_entry->name_joliet[0])) - 1;
|
|
||||||
len = viso_convert_utf8(wtemp, readdir_entry->d_name, wtemp_len);
|
|
||||||
if (len > max_len) {
|
|
||||||
/* Relocate extension if this is a file whose name exceeds the maximum length. */
|
|
||||||
if (!S_ISDIR(last_entry->stats.st_mode)) {
|
|
||||||
wchar_t *wext = wcsrchr(wtemp, L'.');
|
|
||||||
if (wext) {
|
|
||||||
len = wcslen(wext);
|
|
||||||
memmove(wtemp + (max_len - len), wext, len * sizeof(wchar_t));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
len = max_len;
|
|
||||||
}
|
|
||||||
viso_write_wstring(last_entry->name_joliet, wtemp, len, VISO_CHARSET_FN);
|
|
||||||
last_entry->name_joliet[len] = '\0';
|
|
||||||
last_entry->name_joliet_len = len;
|
|
||||||
|
|
||||||
cdrom_image_viso_log("[%08X] %s => [%-12s] %s\n", last_entry, dir->path, last_entry->name_short, last_entry->basename);
|
cdrom_image_viso_log("[%08X] %s => [%-12s] %s\n", last_entry, dir->path, last_entry->name_short, last_entry->basename);
|
||||||
|
|
||||||
/* If this is a directory, add it to the traversal list. */
|
/* If this is a directory, add it to the traversal list. */
|
||||||
@@ -822,7 +830,8 @@ next_dir:
|
|||||||
if (i) {
|
if (i) {
|
||||||
viso_write_wstring((uint16_t *) p, EMU_NAME_W, 16, VISO_CHARSET_A); /* system ID */
|
viso_write_wstring((uint16_t *) p, EMU_NAME_W, 16, VISO_CHARSET_A); /* system ID */
|
||||||
p += 32;
|
p += 32;
|
||||||
mbstowcs(wtemp, basename, 16);
|
wchar_t wtemp[16];
|
||||||
|
viso_convert_utf8(wtemp, basename, 16);
|
||||||
viso_write_wstring((uint16_t *) p, wtemp, 16, VISO_CHARSET_D); /* volume ID */
|
viso_write_wstring((uint16_t *) p, wtemp, 16, VISO_CHARSET_D); /* volume ID */
|
||||||
p += 32;
|
p += 32;
|
||||||
} else {
|
} else {
|
||||||
@@ -1051,35 +1060,38 @@ next_dir:
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
cdrom_image_viso_log("[%08X] %s => %s\n", dir, dir->path, (i & 2) ? dir->basename : dir->name_short);
|
cdrom_image_viso_log("[%08X] %s => %s\n", dir, dir->path, ((i & 2) || (dir == viso->root_dir)) ? dir->basename : dir->name_short);
|
||||||
|
|
||||||
/* Save this directory's path table index and offset. */
|
/* Save this directory's path table index and offset. */
|
||||||
dir->pt_idx = pt_idx;
|
dir->pt_idx = pt_idx;
|
||||||
dir->pt_offsets[i] = ftello64(viso->tf.file);
|
dir->pt_offsets[i] = ftello64(viso->tf.file);
|
||||||
|
|
||||||
/* Fill path table entry. */
|
/* Fill path table entry. */
|
||||||
if (dir == viso->root_dir) /* directory ID length */
|
p = data + 1; /* skip ID length for now */
|
||||||
|
|
||||||
|
*p++ = 0; /* extended attribute length */
|
||||||
|
*((uint32_t *) p) = 0; /* extent location (filled in later) */
|
||||||
|
p += 4;
|
||||||
|
|
||||||
|
*((uint16_t *) p) = (i & 1) ? cpu_to_be16(dir->parent->pt_idx) : cpu_to_le16(dir->parent->pt_idx); /* parent directory number */
|
||||||
|
p += 2;
|
||||||
|
|
||||||
|
if (dir == viso->root_dir) { /* directory ID and length */
|
||||||
data[0] = 1;
|
data[0] = 1;
|
||||||
else if (i & 2)
|
*p = 0x00;
|
||||||
data[0] = dir->name_joliet_len * sizeof(dir->name_joliet[0]);
|
} else if (i & 2) {
|
||||||
else
|
data[0] = viso_fill_fn_joliet(p, dir, 255);
|
||||||
|
} else {
|
||||||
data[0] = strlen(dir->name_short);
|
data[0] = strlen(dir->name_short);
|
||||||
|
memcpy(p, dir->name_short, data[0]);
|
||||||
|
}
|
||||||
|
p += data[0];
|
||||||
|
|
||||||
data[1] = 0; /* extended attribute length */
|
if ((p - data) & 1) /* padding for odd directory ID lengths */
|
||||||
*((uint32_t *) &data[2]) = 0; /* extent location (filled in later) */
|
*p++ = 0x00;
|
||||||
|
|
||||||
*((uint16_t *) &data[6]) = (i & 1) ? cpu_to_be16(dir->parent->pt_idx) : cpu_to_le16(dir->parent->pt_idx); /* parent directory number */
|
|
||||||
|
|
||||||
if (dir == viso->root_dir) /* directory ID */
|
|
||||||
data[8] = 0;
|
|
||||||
else if (i & 2)
|
|
||||||
memcpy(&data[8], dir->name_joliet, data[0]);
|
|
||||||
else
|
|
||||||
memcpy(&data[8], dir->name_short, data[0]);
|
|
||||||
data[8 + data[0]] = 0; /* padding for odd directory ID lengths */
|
|
||||||
|
|
||||||
/* Write path table entry. */
|
/* Write path table entry. */
|
||||||
fwrite(data, 8 + data[0] + (data[0] & 1), 1, viso->tf.file);
|
fwrite(data, p - data, 1, viso->tf.file);
|
||||||
|
|
||||||
/* Increment path table index and stop if it overflows. */
|
/* Increment path table index and stop if it overflows. */
|
||||||
if (++pt_idx == 0)
|
if (++pt_idx == 0)
|
||||||
@@ -1133,7 +1145,7 @@ next_dir:
|
|||||||
viso_pwrite(data, dir->pt_offsets[i << 1] + 2, 4, 1, viso->tf.file); /* little endian */
|
viso_pwrite(data, dir->pt_offsets[i << 1] + 2, 4, 1, viso->tf.file); /* little endian */
|
||||||
viso_pwrite(data + 4, dir->pt_offsets[(i << 1) | 1] + 2, 4, 1, viso->tf.file); /* big endian */
|
viso_pwrite(data + 4, dir->pt_offsets[(i << 1) | 1] + 2, 4, 1, viso->tf.file); /* big endian */
|
||||||
|
|
||||||
if (i) /* clear union if we no longer need path table offsets */
|
if (i) /* overwrite pt_offsets in the union if we no longer need them */
|
||||||
dir->file = NULL;
|
dir->file = NULL;
|
||||||
|
|
||||||
/* Go through entries in this directory. */
|
/* Go through entries in this directory. */
|
||||||
@@ -1144,8 +1156,8 @@ next_dir:
|
|||||||
goto next_entry;
|
goto next_entry;
|
||||||
|
|
||||||
cdrom_image_viso_log("[%08X] %s => %s\n", entry,
|
cdrom_image_viso_log("[%08X] %s => %s\n", entry,
|
||||||
entry->path ? entry->path : ((dir_type == VISO_DIR_PARENT) ? dir->parent->path : dir->path),
|
((dir_type == VISO_DIR_PARENT) ? dir->parent->path : ((dir_type < VISO_DIR_PARENT) ? dir->path : entry->path)),
|
||||||
i ? entry->basename : entry->name_short);
|
((dir_type == VISO_DIR_PARENT) ? ".." : ((dir_type < VISO_DIR_PARENT) ? "." : (i ? entry->basename : entry->name_short))));
|
||||||
|
|
||||||
/* Fill directory record. */
|
/* Fill directory record. */
|
||||||
viso_fill_dir_record(data, entry, dir_type);
|
viso_fill_dir_record(data, entry, dir_type);
|
||||||
@@ -1158,7 +1170,7 @@ next_dir:
|
|||||||
fwrite(p, write, 1, viso->tf.file);
|
fwrite(p, write, 1, viso->tf.file);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write this entry's record's offset. */
|
/* Write this entry's record's offset. This overwrites name_short in the union. */
|
||||||
entry->dr_offsets[i] = ftello64(viso->tf.file);
|
entry->dr_offsets[i] = ftello64(viso->tf.file);
|
||||||
|
|
||||||
/* Write data related to the . and .. pseudo-subdirectories,
|
/* Write data related to the . and .. pseudo-subdirectories,
|
||||||
@@ -1313,8 +1325,6 @@ end:
|
|||||||
cdrom_image_viso_log("VISO: Initialization failed\n");
|
cdrom_image_viso_log("VISO: Initialization failed\n");
|
||||||
if (data)
|
if (data)
|
||||||
free(data);
|
free(data);
|
||||||
if (wtemp)
|
|
||||||
free(wtemp);
|
|
||||||
viso_close(&viso->tf);
|
viso_close(&viso->tf);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user