Beautified the collision avoiding names
This commit is contained in:
parent
afa65e9f2a
commit
b9b5284f22
147
libisofs/tree.c
147
libisofs/tree.c
@ -740,11 +740,10 @@ int check_special(IsoImage *image, mode_t mode)
|
|||||||
|
|
||||||
|
|
||||||
static
|
static
|
||||||
void ascii_increment(char *name, int pos)
|
void ascii_increment(char *name, int len, int pos, int rollover_carry)
|
||||||
{
|
{
|
||||||
int c, len;
|
int c;
|
||||||
|
|
||||||
len = strlen(name);
|
|
||||||
again:;
|
again:;
|
||||||
if (pos < 0 || pos >= len)
|
if (pos < 0 || pos >= len)
|
||||||
pos = len - 1;
|
pos = len - 1;
|
||||||
@ -765,8 +764,7 @@ again:;
|
|||||||
c = '0';
|
c = '0';
|
||||||
name[pos] = c;
|
name[pos] = c;
|
||||||
pos--;
|
pos--;
|
||||||
if (pos >= 0 ||
|
if (pos >= 0 || rollover_carry)
|
||||||
strchr(name, '.') != NULL) /* Do not get caged before last dot */
|
|
||||||
goto again;
|
goto again;
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
@ -778,46 +776,120 @@ again:;
|
|||||||
name[pos] = c;
|
name[pos] = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int insert_underscores(char *name, int *len, int *at_pos, int count,
|
||||||
|
char **new_name)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
LIBISO_ALLOC_MEM(*new_name, char, count + *len + 1);
|
||||||
|
if (*at_pos > 0)
|
||||||
|
memcpy(*new_name, name, *at_pos);
|
||||||
|
if (count > 0)
|
||||||
|
memset(*new_name + *at_pos, '_', count);
|
||||||
|
if (*len > *at_pos)
|
||||||
|
memcpy(*new_name + *at_pos + count, name + *at_pos, *len - *at_pos);
|
||||||
|
(*new_name)[count + *len] = 0;
|
||||||
|
*len += count;
|
||||||
|
*at_pos += count;
|
||||||
|
ret= ISO_SUCCESS;
|
||||||
|
ex:;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int make_incrementable_name(char **name, char **unique_name, int *low_pos,
|
||||||
|
int *rollover_carry, int *pre_check)
|
||||||
|
{
|
||||||
|
char *dpt, *npt;
|
||||||
|
int first, len, ret;
|
||||||
|
|
||||||
|
/* The incrementable part of the file shall have at least 7 characters.
|
||||||
|
There may be up to pow(2.0,32.0)*2048/33 = 266548273400 files.
|
||||||
|
The set of increment result characters has 63 elements.
|
||||||
|
pow(63.0,7.0) is nearly 15 times larger than 266548273400.
|
||||||
|
*/
|
||||||
|
static int min_incr = 7;
|
||||||
|
|
||||||
|
/* At most two suffixes of total length up to 12, like .tar.bz2,
|
||||||
|
shall be preserved. The incrementable part will eventually be
|
||||||
|
padded up.
|
||||||
|
Incrementing begins before the last suffix in any case. But when this
|
||||||
|
rolls over on short prefixes, then long last suffixes will get used
|
||||||
|
as high characters of the incremental part. This is indicated by
|
||||||
|
*rollover_carry which corresponds to the parameter of ascii_increment()
|
||||||
|
with the same name.
|
||||||
|
*/
|
||||||
|
static int max_suffix = 12;
|
||||||
|
|
||||||
|
*rollover_carry = 0;
|
||||||
|
*pre_check = 0;
|
||||||
|
|
||||||
|
len = strlen(*name);
|
||||||
|
|
||||||
|
/* Check if the part before the first dot is long enough.
|
||||||
|
If not, then preserve the last two short suffixes.
|
||||||
|
*/
|
||||||
|
dpt = strchr(*name, '.');
|
||||||
|
if (dpt != NULL)
|
||||||
|
if ((dpt - *name) < min_incr)
|
||||||
|
dpt = strrchr(*name, '.');
|
||||||
|
if (dpt != NULL) {
|
||||||
|
first= (dpt - *name);
|
||||||
|
if (dpt > *name && len - first < max_suffix) {
|
||||||
|
for(npt = dpt - 1; npt >= *name && *npt != '.'; npt--);
|
||||||
|
if (npt >= *name) {
|
||||||
|
if (len - (npt - *name) <= max_suffix) {
|
||||||
|
first= (npt - *name);
|
||||||
|
dpt = npt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
first= len;
|
||||||
|
if (first < min_incr && (len - first) <= max_suffix) {
|
||||||
|
ret = insert_underscores(*name, &len, &first, min_incr - first,
|
||||||
|
unique_name);
|
||||||
|
if (ret < 0)
|
||||||
|
goto ex;
|
||||||
|
*pre_check = 1; /* It might now already be unique */
|
||||||
|
|
||||||
|
} else if (len < 64) {
|
||||||
|
/* Insert an underscore to preserve the original name at least for the
|
||||||
|
first few increments
|
||||||
|
*/
|
||||||
|
ret = insert_underscores(*name, &len, &first, 1, unique_name);
|
||||||
|
if (ret < 0)
|
||||||
|
goto ex;
|
||||||
|
*pre_check = 1;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
LIBISO_ALLOC_MEM(*unique_name, char, len + 1);
|
||||||
|
memcpy(*unique_name, *name, len);
|
||||||
|
if (first < min_incr)
|
||||||
|
*rollover_carry = 1; /* Do not get caged before the dots */
|
||||||
|
}
|
||||||
|
(*unique_name)[len] = 0;
|
||||||
|
*low_pos = first - 1;
|
||||||
|
ret = 1;
|
||||||
|
ex:;
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
int make_really_unique_name(IsoDir *parent, char **name, char **unique_name,
|
int make_really_unique_name(IsoDir *parent, char **name, char **unique_name,
|
||||||
IsoNode ***pos, int flag)
|
IsoNode ***pos, int flag)
|
||||||
{
|
{
|
||||||
int len, ret, pre_check = 0, ascii_idx = -1, first;
|
int ret, rollover_carry = 0, pre_check = 0, ascii_idx = -1, len;
|
||||||
char *dpt;
|
|
||||||
|
|
||||||
len = strlen(*name);
|
ret = make_incrementable_name(name, unique_name, &ascii_idx,
|
||||||
if (len < 7) {
|
&rollover_carry, &pre_check);
|
||||||
/* There may be up to pow(2.0,32.0)*2048/33 = 266548273400 files
|
if (ret < 0)
|
||||||
The set of increment result characters has 63 elements.
|
goto ex;
|
||||||
pow(63.0,7.0) is nearly 15 times larger than 266548273400.
|
len = strlen(*unique_name);
|
||||||
*/
|
|
||||||
/* Insert underscores before last dot */
|
|
||||||
LIBISO_ALLOC_MEM(*unique_name, char, 7 + 1);
|
|
||||||
first = len;
|
|
||||||
dpt = strrchr(*name, '.');
|
|
||||||
if (dpt != NULL)
|
|
||||||
first = (dpt - *name);
|
|
||||||
if (first > 0)
|
|
||||||
memcpy(*unique_name, *name, first);
|
|
||||||
memset(*unique_name + first, '_', 7 - len);
|
|
||||||
if (len > first)
|
|
||||||
memcpy(*unique_name + (7 - (len - first)), *name + first,
|
|
||||||
len - first);
|
|
||||||
len = 7;
|
|
||||||
pre_check = 1; /* It might now already be unique */
|
|
||||||
} else {
|
|
||||||
LIBISO_ALLOC_MEM(*unique_name, char, len + 1);
|
|
||||||
memcpy(*unique_name, *name, len);
|
|
||||||
}
|
|
||||||
(*unique_name)[len] = 0;
|
|
||||||
|
|
||||||
dpt = strrchr(*unique_name, '.');
|
|
||||||
if (dpt != NULL)
|
|
||||||
ascii_idx = (dpt - *unique_name) - 1; /* Begin before last dot */
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (!pre_check)
|
if (!pre_check)
|
||||||
ascii_increment(*unique_name, ascii_idx);
|
ascii_increment(*unique_name, len, ascii_idx, !!rollover_carry);
|
||||||
else
|
else
|
||||||
pre_check = 0;
|
pre_check = 0;
|
||||||
ret = iso_dir_exists(parent, *unique_name, pos);
|
ret = iso_dir_exists(parent, *unique_name, pos);
|
||||||
@ -836,7 +908,6 @@ ex:;
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Recursively add a given directory to the image tree.
|
* Recursively add a given directory to the image tree.
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user