lfn.c (dosfstools-4.1) | : | lfn.c (dosfstools-4.2) | ||
---|---|---|---|---|
skipping to change at line 77 | skipping to change at line 77 | |||
'm', 'n', 'o', 'p', 'q', 'r', 's', 't', | 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', | |||
'u', 'v', 'w', 'x', 'y', 'z', '+', '-' | 'u', 'v', 'w', 'x', 'y', 'z', '+', '-' | |||
}; | }; | |||
/* This defines which unicode chars are directly convertable to ISO-8859-1 */ | /* This defines which unicode chars are directly convertable to ISO-8859-1 */ | |||
#define UNICODE_CONVERTABLE(cl,ch) (ch == 0 && (cl < 0x80 || cl >= 0xa0)) | #define UNICODE_CONVERTABLE(cl,ch) (ch == 0 && (cl < 0x80 || cl >= 0xa0)) | |||
/* for maxlen param */ | /* for maxlen param */ | |||
#define UNTIL_0 INT_MAX | #define UNTIL_0 INT_MAX | |||
/* Convert name part in 'lfn' from unicode to ASCII */ | ||||
#define CNV_THIS_PART(lfn) \ | ||||
({ \ | ||||
unsigned char __part_uni[CHARS_PER_LFN*2]; \ | ||||
copy_lfn_part( __part_uni, lfn ); \ | ||||
cnv_unicode( __part_uni, CHARS_PER_LFN, 0 ); \ | ||||
}) | ||||
/* Convert name parts collected so far (from previous slots) from unicode to | /* Convert name parts collected so far (from previous slots) from unicode to | |||
* ASCII */ | * ASCII */ | |||
#define CNV_PARTS_SO_FAR() \ | #define CNV_PARTS_SO_FAR() \ | |||
(cnv_unicode( lfn_unicode+(lfn_slot*CHARS_PER_LFN*2), \ | (cnv_unicode( lfn_unicode+(lfn_slot*CHARS_PER_LFN*2), \ | |||
lfn_parts*CHARS_PER_LFN, 0 )) | lfn_parts*CHARS_PER_LFN, 0 )) | |||
#define BYTES_TO_WCHAR(cl,ch) ((wchar_t)((unsigned)(cl) + ((unsigned)(ch) << 8)) ) | #define BYTES_TO_WCHAR(cl,ch) ((wchar_t)((unsigned)(cl) + ((unsigned)(ch) << 8)) ) | |||
static size_t mbslen(wchar_t x) | static size_t mbslen(wchar_t x) | |||
{ | { | |||
wchar_t wstr[] = { x, 0 }; | wchar_t wstr[] = { x, 0 }; | |||
skipping to change at line 158 | skipping to change at line 150 | |||
return (char *)out; | return (char *)out; | |||
} | } | |||
static void copy_lfn_part(unsigned char *dst, LFN_ENT * lfn) | static void copy_lfn_part(unsigned char *dst, LFN_ENT * lfn) | |||
{ | { | |||
memcpy(dst, lfn->name0_4, 10); | memcpy(dst, lfn->name0_4, 10); | |||
memcpy(dst + 10, lfn->name5_10, 12); | memcpy(dst + 10, lfn->name5_10, 12); | |||
memcpy(dst + 22, lfn->name11_12, 4); | memcpy(dst + 22, lfn->name11_12, 4); | |||
} | } | |||
/* Convert name part in 'lfn' from unicode to ASCII */ | ||||
static inline char *cnv_this_part(LFN_ENT *lfn) | ||||
{ | ||||
unsigned char part_uni[CHARS_PER_LFN * 2]; | ||||
copy_lfn_part(part_uni, lfn); | ||||
return cnv_unicode(part_uni, CHARS_PER_LFN, 0); | ||||
} | ||||
static void clear_lfn_slots(int start, int end) | static void clear_lfn_slots(int start, int end) | |||
{ | { | |||
int i; | int i; | |||
LFN_ENT empty; | LFN_ENT empty; | |||
/* New dir entry is zeroed except first byte, which is set to 0xe5. | /* New dir entry is zeroed except first byte, which is set to 0xe5. | |||
* This is to avoid that some FAT-reading OSes (not Linux! ;) stop reading | * This is to avoid that some FAT-reading OSes (not Linux! ;) stop reading | |||
* a directory at the first zero entry... | * a directory at the first zero entry... | |||
*/ | */ | |||
memset(&empty, 0, sizeof(empty)); | memset(&empty, 0, sizeof(empty)); | |||
skipping to change at line 225 | skipping to change at line 225 | |||
/* There is already a LFN "in progess", so it is an error that a | /* There is already a LFN "in progess", so it is an error that a | |||
* new start entry is here. */ | * new start entry is here. */ | |||
/* Causes: 1) if slot# == expected: start bit set mysteriously, 2) | /* Causes: 1) if slot# == expected: start bit set mysteriously, 2) | |||
* old LFN overwritten by new one */ | * old LFN overwritten by new one */ | |||
/* Fixes: 1) delete previous LFN 2) if slot# == expected and | /* Fixes: 1) delete previous LFN 2) if slot# == expected and | |||
* checksum ok: clear start bit */ | * checksum ok: clear start bit */ | |||
/* XXX: Should delay that until next LFN known (then can better | /* XXX: Should delay that until next LFN known (then can better | |||
* display the name) */ | * display the name) */ | |||
printf("A new long file name starts within an old one.\n"); | printf("A new long file name starts within an old one.\n"); | |||
if (slot == lfn_slot && lfn->alias_checksum == lfn_checksum) { | if (slot == lfn_slot && lfn->alias_checksum == lfn_checksum) { | |||
char *part1 = CNV_THIS_PART(lfn); | char *part1 = cnv_this_part(lfn); | |||
char *part2 = CNV_PARTS_SO_FAR(); | char *part2 = CNV_PARTS_SO_FAR(); | |||
printf(" It could be that the LFN start bit is wrong here\n" | printf(" It could be that the LFN start bit is wrong here\n" | |||
" if \"%s\" seems to match \"%s\".\n", part1, part2); | " if \"%s\" seems to match \"%s\".\n", part1, part2); | |||
free(part1); | free(part1); | |||
free(part2); | free(part2); | |||
can_clear = 1; | can_clear = 1; | |||
} | } | |||
if (interactive) { | switch (get_choice(2, " Not auto-correcting this.", | |||
printf("1: Delete previous LFN\n2: Leave it as it is.\n"); | can_clear ? 3 : 2, | |||
if (can_clear) | 1, "Delete previous LFN", | |||
printf("3: Clear start bit and concatenate LFNs\n"); | 2, "Leave it as it is", | |||
} else | 3, "Clear start bit and concatenate LFNs")) { | |||
printf(" Not auto-correcting this.\n"); | case 1: | |||
if (interactive) { | clear_lfn_slots(0, lfn_parts - 1); | |||
switch (get_key(can_clear ? "123" : "12", "?")) { | lfn_reset(); | |||
case '1': | break; | |||
clear_lfn_slots(0, lfn_parts - 1); | case 2: | |||
lfn_reset(); | break; | |||
break; | case 3: | |||
case '2': | lfn->id &= ~LFN_ID_START; | |||
break; | fs_write(dir_offset + offsetof(LFN_ENT, id), | |||
case '3': | sizeof(lfn->id), &lfn->id); | |||
lfn->id &= ~LFN_ID_START; | break; | |||
fs_write(dir_offset + offsetof(LFN_ENT, id), | ||||
sizeof(lfn->id), &lfn->id); | ||||
break; | ||||
} | ||||
} | } | |||
} | } | |||
lfn_slot = slot; | lfn_slot = slot; | |||
lfn_checksum = lfn->alias_checksum; | lfn_checksum = lfn->alias_checksum; | |||
lfn_unicode = alloc((lfn_slot * CHARS_PER_LFN + 1) * 2); | lfn_unicode = alloc((lfn_slot * CHARS_PER_LFN + 1) * 2); | |||
lfn_offsets = alloc(lfn_slot * sizeof(off_t)); | lfn_offsets = alloc(lfn_slot * sizeof(off_t)); | |||
lfn_parts = 0; | lfn_parts = 0; | |||
} else if (lfn_slot == -1 && slot != 0) { | } else if (lfn_slot == -1 && slot != 0) { | |||
/* No LFN in progress, but slot found; start bit missing */ | /* No LFN in progress, but slot found; start bit missing */ | |||
/* Causes: 1) start bit got lost, 2) Previous slot with start bit got | /* Causes: 1) start bit got lost, 2) Previous slot with start bit got | |||
* lost */ | * lost */ | |||
/* Fixes: 1) delete LFN, 2) set start bit */ | /* Fixes: 1) delete LFN, 2) set start bit */ | |||
char *part = CNV_THIS_PART(lfn); | char *part = cnv_this_part(lfn); | |||
printf("Long filename fragment \"%s\" found outside a LFN " | printf("Long filename fragment \"%s\" found outside a LFN " | |||
"sequence.\n (Maybe the start bit is missing on the " | "sequence.\n (Maybe the start bit is missing on the " | |||
"last fragment)\n", part); | "last fragment)\n", part); | |||
free(part); | free(part); | |||
if (interactive) { | switch (get_choice(2, " Not auto-correcting this.", | |||
printf("1: Delete fragment\n2: Leave it as it is.\n" | 3, | |||
"3: Set start bit\n"); | 1, "Delete fragment", | |||
} else | 2, "Leave it as it is", | |||
printf(" Not auto-correcting this.\n"); | 3, "Set start bit")) { | |||
switch (interactive ? get_key("123", "?") : '2') { | case 1: | |||
case '1': | ||||
if (!lfn_offsets) | if (!lfn_offsets) | |||
lfn_offsets = alloc(sizeof(off_t)); | lfn_offsets = alloc(sizeof(off_t)); | |||
lfn_offsets[0] = dir_offset; | lfn_offsets[0] = dir_offset; | |||
clear_lfn_slots(0, 0); | clear_lfn_slots(0, 0); | |||
lfn_reset(); | lfn_reset(); | |||
return; | return; | |||
case '2': | case 2: | |||
lfn_reset(); | lfn_reset(); | |||
return; | return; | |||
case '3': | case 3: | |||
lfn->id |= LFN_ID_START; | lfn->id |= LFN_ID_START; | |||
fs_write(dir_offset + offsetof(LFN_ENT, id), | fs_write(dir_offset + offsetof(LFN_ENT, id), | |||
sizeof(lfn->id), &lfn->id); | sizeof(lfn->id), &lfn->id); | |||
lfn_slot = slot; | lfn_slot = slot; | |||
lfn_checksum = lfn->alias_checksum; | lfn_checksum = lfn->alias_checksum; | |||
lfn_unicode = alloc((lfn_slot * CHARS_PER_LFN + 1) * 2); | lfn_unicode = alloc((lfn_slot * CHARS_PER_LFN + 1) * 2); | |||
lfn_offsets = alloc(lfn_slot * sizeof(off_t)); | lfn_offsets = alloc(lfn_slot * sizeof(off_t)); | |||
lfn_parts = 0; | lfn_parts = 0; | |||
break; | break; | |||
} | } | |||
} else if (slot != lfn_slot) { | } else if (slot != lfn_slot) { | |||
/* wrong sequence number */ | /* wrong sequence number */ | |||
/* Causes: 1) seq-no destroyed */ | /* Causes: 1) seq-no destroyed */ | |||
/* Fixes: 1) delete LFN, 2) fix number (maybe only if following parts | /* Fixes: 1) delete LFN, 2) fix number (maybe only if following parts | |||
* are ok?, maybe only if checksum is ok?) (Attention: space | * are ok?, maybe only if checksum is ok?) (Attention: space | |||
* for name was allocated before!) */ | * for name was allocated before!) */ | |||
int can_fix = 0; | int can_fix = 0; | |||
printf("Unexpected long filename sequence number " | printf("Unexpected long filename sequence number " | |||
"(%d vs. expected %d).\n", slot, lfn_slot); | "(%d vs. expected %d).\n", slot, lfn_slot); | |||
if (lfn->alias_checksum == lfn_checksum && lfn_slot > 0) { | if (lfn->alias_checksum == lfn_checksum && lfn_slot > 0) { | |||
char *part1 = CNV_THIS_PART(lfn); | char *part1 = cnv_this_part(lfn); | |||
char *part2 = CNV_PARTS_SO_FAR(); | char *part2 = CNV_PARTS_SO_FAR(); | |||
printf(" It could be that just the number is wrong\n" | printf(" It could be that just the number is wrong\n" | |||
" if \"%s\" seems to match \"%s\".\n", part1, part2); | " if \"%s\" seems to match \"%s\".\n", part1, part2); | |||
free(part1); | free(part1); | |||
free(part2); | free(part2); | |||
can_fix = 1; | can_fix = 1; | |||
} | } | |||
if (interactive) { | switch (get_choice(2, " Not auto-correcting this.", | |||
printf | can_fix ? 3 : 2, | |||
("1: Delete LFN\n2: Leave it as it is (and ignore LFN so far)\n") | 1, "Delete LFN", | |||
; | 2, "Leave it as it is (and ignore LFN so far)", | |||
if (can_fix) | 3, "Correct sequence number")) { | |||
printf("3: Correct sequence number\n"); | case 1: | |||
} else | ||||
printf(" Not auto-correcting this.\n"); | ||||
switch (interactive ? get_key(can_fix ? "123" : "12", "?") : '2') { | ||||
case '1': | ||||
if (!lfn_offsets) { | if (!lfn_offsets) { | |||
lfn_offsets = alloc(sizeof(off_t)); | lfn_offsets = alloc(sizeof(off_t)); | |||
lfn_parts = 0; | lfn_parts = 0; | |||
} | } | |||
lfn_offsets[lfn_parts++] = dir_offset; | lfn_offsets[lfn_parts++] = dir_offset; | |||
clear_lfn_slots(0, lfn_parts - 1); | clear_lfn_slots(0, lfn_parts - 1); | |||
lfn_reset(); | lfn_reset(); | |||
return; | return; | |||
case '2': | case 2: | |||
lfn_reset(); | lfn_reset(); | |||
return; | return; | |||
case '3': | case 3: | |||
lfn->id = (lfn->id & ~LFN_ID_SLOTMASK) | lfn_slot; | lfn->id = (lfn->id & ~LFN_ID_SLOTMASK) | lfn_slot; | |||
fs_write(dir_offset + offsetof(LFN_ENT, id), | fs_write(dir_offset + offsetof(LFN_ENT, id), | |||
sizeof(lfn->id), &lfn->id); | sizeof(lfn->id), &lfn->id); | |||
break; | break; | |||
} | } | |||
} | } | |||
if (lfn->alias_checksum != lfn_checksum) { | if (lfn->alias_checksum != lfn_checksum) { | |||
/* checksum mismatch */ | /* checksum mismatch */ | |||
/* Causes: 1) checksum field here destroyed */ | /* Causes: 1) checksum field here destroyed */ | |||
/* Fixes: 1) delete LFN, 2) fix checksum */ | /* Fixes: 1) delete LFN, 2) fix checksum */ | |||
printf("Checksum in long filename part wrong " | printf("Checksum in long filename part wrong " | |||
"(%02x vs. expected %02x).\n", | "(%02x vs. expected %02x).\n", | |||
lfn->alias_checksum, lfn_checksum); | lfn->alias_checksum, lfn_checksum); | |||
if (interactive) { | switch (get_choice(2, " Not auto-correcting this.", | |||
printf("1: Delete LFN\n2: Leave it as it is.\n" | 3, | |||
"3: Correct checksum\n"); | 1, "Delete LFN", | |||
} else | 2, "Leave it as it is", | |||
printf(" Not auto-correcting this.\n"); | 3, "Correct checksum")) { | |||
if (interactive) { | case 1: | |||
switch (get_key("123", "?")) { | lfn_offsets[lfn_parts++] = dir_offset; | |||
case '1': | clear_lfn_slots(0, lfn_parts - 1); | |||
lfn_offsets[lfn_parts++] = dir_offset; | lfn_reset(); | |||
clear_lfn_slots(0, lfn_parts - 1); | return; | |||
lfn_reset(); | case 2: | |||
return; | break; | |||
case '2': | case 3: | |||
break; | lfn->alias_checksum = lfn_checksum; | |||
case '3': | fs_write(dir_offset + offsetof(LFN_ENT, alias_checksum), | |||
lfn->alias_checksum = lfn_checksum; | sizeof(lfn->alias_checksum), &lfn->alias_checksum); | |||
fs_write(dir_offset + offsetof(LFN_ENT, alias_checksum), | break; | |||
sizeof(lfn->alias_checksum), &lfn->alias_checksum); | ||||
break; | ||||
} | ||||
} | } | |||
} | } | |||
if (lfn_slot != -1) { | if (lfn_slot != -1) { | |||
lfn_slot--; | lfn_slot--; | |||
offset = lfn_slot * CHARS_PER_LFN * 2; | offset = lfn_slot * CHARS_PER_LFN * 2; | |||
copy_lfn_part(lfn_unicode + offset, lfn); | copy_lfn_part(lfn_unicode + offset, lfn); | |||
if (lfn->id & LFN_ID_START) | if (lfn->id & LFN_ID_START) | |||
lfn_unicode[offset + 26] = lfn_unicode[offset + 27] = 0; | lfn_unicode[offset + 26] = lfn_unicode[offset + 27] = 0; | |||
lfn_offsets[lfn_parts++] = dir_offset; | lfn_offsets[lfn_parts++] = dir_offset; | |||
} | } | |||
if (lfn->reserved != 0) { | if (lfn->reserved != 0) { | |||
printf("Reserved field in VFAT long filename slot is not 0 " | printf("Reserved field in VFAT long filename slot is not 0 " | |||
"(but 0x%02x).\n", lfn->reserved); | "(but 0x%02x).\n", lfn->reserved); | |||
if (interactive) | if (get_choice(1, "Auto-setting to 0.", | |||
printf("1: Fix.\n2: Leave it.\n"); | 2, | |||
else | 1, "Fix", | |||
printf("Auto-setting to 0.\n"); | 2, "Leave it") == 1) { | |||
if (!interactive || get_key("12", "?") == '1') { | ||||
lfn->reserved = 0; | lfn->reserved = 0; | |||
fs_write(dir_offset + offsetof(LFN_ENT, reserved), | fs_write(dir_offset + offsetof(LFN_ENT, reserved), | |||
sizeof(lfn->reserved), &lfn->reserved); | sizeof(lfn->reserved), &lfn->reserved); | |||
} | } | |||
} | } | |||
if (lfn->start != htole16(0)) { | if (lfn->start != htole16(0)) { | |||
printf("Start cluster field in VFAT long filename slot is not 0 " | printf("Start cluster field in VFAT long filename slot is not 0 " | |||
"(but 0x%04x).\n", lfn->start); | "(but 0x%04x).\n", lfn->start); | |||
if (interactive) | if (get_choice(1, "Auto-setting to 0.", | |||
printf("1: Fix.\n2: Leave it.\n"); | 2, | |||
else | 1, "Fix", | |||
printf("Auto-setting to 0.\n"); | 2, "Leave it") == 1) { | |||
if (!interactive || get_key("12", "?") == '1') { | ||||
lfn->start = htole16(0); | lfn->start = htole16(0); | |||
fs_write(dir_offset + offsetof(LFN_ENT, start), | fs_write(dir_offset + offsetof(LFN_ENT, start), | |||
sizeof(lfn->start), &lfn->start); | sizeof(lfn->start), &lfn->start); | |||
} | } | |||
} | } | |||
} | } | |||
/* This function is always called when de->attr != VFAT_LN_ATTR is found, to | /* This function is always called when de->attr != VFAT_LN_ATTR is found, to | |||
* retrieve the previously constructed LFN. */ | * retrieve the previously constructed LFN. */ | |||
char *lfn_get(DIR_ENT * de, off_t * lfn_offset) | char *lfn_get(DIR_ENT * de, off_t * lfn_offset) | |||
skipping to change at line 439 | skipping to change at line 426 | |||
return NULL; | return NULL; | |||
if (lfn_slot != 0) { | if (lfn_slot != 0) { | |||
/* The long name isn't finished yet. */ | /* The long name isn't finished yet. */ | |||
/* Causes: 1) LFN slot overwritten by non-VFAT aware tool */ | /* Causes: 1) LFN slot overwritten by non-VFAT aware tool */ | |||
/* Fixes: 1) delete LFN 2) move overwriting entry to somewhere else | /* Fixes: 1) delete LFN 2) move overwriting entry to somewhere else | |||
* and let user enter missing part of LFN (hard to do :-() | * and let user enter missing part of LFN (hard to do :-() | |||
* 3) renumber entries and truncate name */ | * 3) renumber entries and truncate name */ | |||
char *long_name = CNV_PARTS_SO_FAR(); | char *long_name = CNV_PARTS_SO_FAR(); | |||
char *short_name = file_name(de->name); | char *short_name = file_name(de->name); | |||
char *fix_num_string; | ||||
int choice; | ||||
printf("Unfinished long file name \"%s\".\n" | printf("Unfinished long file name \"%s\".\n" | |||
" (Start may have been overwritten by %s)\n", | " (Start may have been overwritten by %s)\n", | |||
long_name, short_name); | long_name, short_name); | |||
free(long_name); | free(long_name); | |||
if (interactive) { | ||||
printf("1: Delete LFN\n2: Leave it as it is.\n" | xasprintf(&fix_num_string, | |||
"3: Fix numbering (truncates long name and attaches " | "Fix numbering (truncates long name and attaches " | |||
"it to short name %s)\n", short_name); | "it to short name %s)", short_name); | |||
} else | choice = get_choice(2, " Not auto-correcting this.", | |||
printf(" Not auto-correcting this.\n"); | 3, | |||
switch (interactive ? get_key("123", "?") : '2') { | 1, "Delete LFN", | |||
case '1': | 2, "Leave it as it is", | |||
3, fix_num_string); | ||||
free(fix_num_string); | ||||
switch (choice) { | ||||
case 1: | ||||
clear_lfn_slots(0, lfn_parts - 1); | clear_lfn_slots(0, lfn_parts - 1); | |||
lfn_reset(); | lfn_reset(); | |||
return NULL; | return NULL; | |||
case '2': | case 2: | |||
lfn_reset(); | lfn_reset(); | |||
return NULL; | return NULL; | |||
case '3': | case 3: | |||
for (i = 0; i < lfn_parts; ++i) { | for (i = 0; i < lfn_parts; ++i) { | |||
uint8_t id = (lfn_parts - i) | (i == 0 ? LFN_ID_START : 0); | uint8_t id = (lfn_parts - i) | (i == 0 ? LFN_ID_START : 0); | |||
fs_write(lfn_offsets[i] + offsetof(LFN_ENT, id), | fs_write(lfn_offsets[i] + offsetof(LFN_ENT, id), | |||
sizeof(id), &id); | sizeof(id), &id); | |||
} | } | |||
memmove(lfn_unicode, lfn_unicode + lfn_slot * CHARS_PER_LFN * 2, | memmove(lfn_unicode, lfn_unicode + lfn_slot * CHARS_PER_LFN * 2, | |||
lfn_parts * CHARS_PER_LFN * 2); | lfn_parts * CHARS_PER_LFN * 2); | |||
break; | break; | |||
} | } | |||
} | } | |||
for (sum = 0, i = 0; i < MSDOS_NAME; i++) | for (sum = 0, i = 0; i < MSDOS_NAME; i++) | |||
sum = (((sum & 1) << 7) | ((sum & 0xfe) >> 1)) + de->name[i]; | sum = (((sum & 1) << 7) | ((sum & 0xfe) >> 1)) + de->name[i]; | |||
if (sum != lfn_checksum) { | if (sum != lfn_checksum) { | |||
/* checksum doesn't match, long name doesn't apply to this alias */ | /* checksum doesn't match, long name doesn't apply to this alias */ | |||
/* Causes: 1) alias renamed */ | /* Causes: 1) alias renamed */ | |||
/* Fixes: 1) Fix checksum in LFN entries */ | /* Fixes: 1) Fix checksum in LFN entries */ | |||
char *long_name = CNV_PARTS_SO_FAR(); | char *long_name = CNV_PARTS_SO_FAR(); | |||
char *short_name = file_name(de->name); | char *short_name = file_name(de->name); | |||
char *fix_check_string; | ||||
int choice; | ||||
printf("Wrong checksum for long file name \"%s\".\n" | printf("Wrong checksum for long file name \"%s\".\n" | |||
" (Short name %s may have changed without updating the long name) \n", | " (Short name %s may have changed without updating the long name) \n", | |||
long_name, short_name); | long_name, short_name); | |||
free(long_name); | free(long_name); | |||
if (interactive) { | ||||
printf("1: Delete LFN\n2: Leave it as it is.\n" | xasprintf(&fix_check_string, | |||
"3: Fix checksum (attaches to short name %s)\n", short_name); | "Fix checksum (attaches to short name %s)", short_name); | |||
} else | choice = get_choice(9, " Not auto-correcting this.", | |||
printf(" Not auto-correcting this.\n"); | 3, | |||
if (interactive) { | 1, "Delete LFN", | |||
switch (get_key("123", "?")) { | 2, "Leave it as it is", | |||
case '1': | 3, fix_check_string); | |||
clear_lfn_slots(0, lfn_parts - 1); | free(fix_check_string); | |||
lfn_reset(); | ||||
return NULL; | switch (choice) { | |||
case '2': | case 1: | |||
lfn_reset(); | clear_lfn_slots(0, lfn_parts - 1); | |||
return NULL; | lfn_reset(); | |||
case '3': | return NULL; | |||
for (i = 0; i < lfn_parts; ++i) { | case 2: | |||
fs_write(lfn_offsets[i] + offsetof(LFN_ENT, alias_checksum), | lfn_reset(); | |||
sizeof(sum), &sum); | return NULL; | |||
} | case 3: | |||
break; | for (i = 0; i < lfn_parts; ++i) { | |||
fs_write(lfn_offsets[i] + offsetof(LFN_ENT, alias_checksum), | ||||
sizeof(sum), &sum); | ||||
} | } | |||
break; | ||||
} | } | |||
} | } | |||
*lfn_offset = lfn_offsets[0]; | *lfn_offset = lfn_offsets[0]; | |||
lfn = cnv_unicode(lfn_unicode, UNTIL_0, 1); | lfn = cnv_unicode(lfn_unicode, UNTIL_0, 1); | |||
lfn_reset(); | lfn_reset(); | |||
return (lfn); | return (lfn); | |||
} | } | |||
void lfn_check_orphaned(void) | void lfn_check_orphaned(void) | |||
{ | { | |||
char *long_name; | char *long_name; | |||
if (lfn_slot == -1) | if (lfn_slot == -1) | |||
return; | return; | |||
long_name = CNV_PARTS_SO_FAR(); | long_name = CNV_PARTS_SO_FAR(); | |||
printf("Orphaned long file name part \"%s\"\n", long_name); | printf("Orphaned long file name part \"%s\"\n", long_name); | |||
free(long_name); | free(long_name); | |||
if (interactive) | if (get_choice(1, " Auto-deleting.", | |||
printf("1: Delete.\n2: Leave it.\n"); | 2, | |||
else | 1, "Delete", | |||
printf(" Auto-deleting.\n"); | 2, "Leave it") == 1) { | |||
if (!interactive || get_key("12", "?") == '1') { | ||||
clear_lfn_slots(0, lfn_parts - 1); | clear_lfn_slots(0, lfn_parts - 1); | |||
} | } | |||
lfn_reset(); | lfn_reset(); | |||
} | } | |||
End of changes. 23 change blocks. | ||||
117 lines changed or deleted | 116 lines changed or added |