Improved handling of unconvertable file names and name collsions during iso_image_import()
This commit is contained in:
parent
60eb7e883c
commit
44f475a4ef
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
* Copyright (c) 2009 - 2011 Thomas Schmitt
|
* Copyright (c) 2009 - 2014 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* This file is part of the libisofs project; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License version 2
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -96,7 +96,7 @@ int default_create_file(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
|
|
||||||
static
|
static
|
||||||
int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
||||||
IsoFileSource *src, IsoNode **node)
|
IsoFileSource *src, char *in_name, IsoNode **node)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct stat info;
|
struct stat info;
|
||||||
@ -122,7 +122,15 @@ int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (in_name == NULL) {
|
||||||
name = iso_file_source_get_name(src);
|
name = iso_file_source_get_name(src);
|
||||||
|
} else {
|
||||||
|
name = strdup(in_name);
|
||||||
|
if (name == NULL) {
|
||||||
|
ret = ISO_OUT_OF_MEM; goto ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (strlen(name) > LIBISOFS_NODE_NAME_MAX)
|
if (strlen(name) > LIBISOFS_NODE_NAME_MAX)
|
||||||
name[LIBISOFS_NODE_NAME_MAX] = 0;
|
name[LIBISOFS_NODE_NAME_MAX] = 0;
|
||||||
fs = iso_file_source_get_filesystem(src);
|
fs = iso_file_source_get_filesystem(src);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
|
* Copyright (c) 2014 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* This file is part of the libisofs project; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License version 2
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -47,6 +48,7 @@ struct Iso_Node_Builder
|
|||||||
* Create a new IsoNode from a IsoFileSource. The type of the node to be
|
* Create a new IsoNode from a IsoFileSource. The type of the node to be
|
||||||
* created is determined from the type of the file source. Name,
|
* created is determined from the type of the file source. Name,
|
||||||
* permissions and other attributes are taken from source file.
|
* permissions and other attributes are taken from source file.
|
||||||
|
* But name may be overridden by parameter name if it is not NULL.
|
||||||
*
|
*
|
||||||
* Note that the src is never unref, so you need to free it.
|
* Note that the src is never unref, so you need to free it.
|
||||||
*
|
*
|
||||||
@ -54,7 +56,7 @@ struct Iso_Node_Builder
|
|||||||
* 1 on success, < 0 on error
|
* 1 on success, < 0 on error
|
||||||
*/
|
*/
|
||||||
int (*create_node)(IsoNodeBuilder *builder, IsoImage *image,
|
int (*create_node)(IsoNodeBuilder *builder, IsoImage *image,
|
||||||
IsoFileSource *src, IsoNode **node);
|
IsoFileSource *src, char *name, IsoNode **node);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Free implementation specific data. Should never be called by user.
|
* Free implementation specific data. Should never be called by user.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
* Copyright (c) 2009 - 2011 Thomas Schmitt
|
* Copyright (c) 2009 - 2014 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* This file is part of the libisofs project; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License version 2
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -1237,15 +1237,67 @@ int iso_ifs_source_get_zf(IsoFileSource *src, int *header_size_div4,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
int make_hopefully_unique_name(_ImageFsData *fsdata,
|
||||||
|
char *str, size_t len, char **name)
|
||||||
|
{
|
||||||
|
int ret, name_len, i;
|
||||||
|
char c, *smashed = NULL, md5[16];
|
||||||
|
void *md5_context = NULL;
|
||||||
|
|
||||||
|
/* Shorten so that 32 characters of MD5 fit.
|
||||||
|
If shorter than 8, pad up to 8 by '_'.
|
||||||
|
Smash characters to [0-9A-Za-z_.].
|
||||||
|
Append MD5 of original str as hex digits.
|
||||||
|
*/
|
||||||
|
name_len = len > 223 ? 223 : len;
|
||||||
|
LIBISO_ALLOC_MEM(smashed, char, (name_len >= 8 ? name_len : 8) + 32 + 1);
|
||||||
|
memcpy(smashed, str, name_len);
|
||||||
|
for (; name_len < 8; name_len++)
|
||||||
|
smashed[name_len] = '_';
|
||||||
|
smashed[name_len] = 0;
|
||||||
|
for (i = 0; i < name_len; i++) {
|
||||||
|
c = smashed[i];
|
||||||
|
if (c == '.' || (c >= '0' && c <= '9') ||
|
||||||
|
c == '_' || (c >= 'a' && c <= 'z'))
|
||||||
|
continue;
|
||||||
|
smashed[i] = '_';
|
||||||
|
}
|
||||||
|
ret = iso_md5_start(&md5_context);
|
||||||
|
if (ret != 1)
|
||||||
|
goto ex;
|
||||||
|
ret = iso_md5_compute(md5_context, str, len);
|
||||||
|
if (ret != 1)
|
||||||
|
goto ex;
|
||||||
|
ret = iso_md5_end(&md5_context, md5);
|
||||||
|
if (ret != 1)
|
||||||
|
goto ex;
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
sprintf(smashed + i * 2 + name_len, "%2.2x",
|
||||||
|
((unsigned char *) md5)[i]);
|
||||||
|
name_len += 32;
|
||||||
|
smashed[name_len] = 0;
|
||||||
|
*name = smashed; smashed = NULL;
|
||||||
|
|
||||||
|
ret = ISO_SUCCESS;
|
||||||
|
ex:
|
||||||
|
LIBISO_FREE_MEM(smashed);
|
||||||
|
if (md5_context != NULL)
|
||||||
|
iso_md5_end(&md5_context, md5);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read a file name from a directory record, doing the needed charset
|
* Read a file name from a directory record, doing the needed charset
|
||||||
* conversion
|
* conversion
|
||||||
*/
|
*/
|
||||||
static
|
static
|
||||||
char *get_name(_ImageFsData *fsdata, const char *str, size_t len)
|
char *get_name(_ImageFsData *fsdata, char *str, size_t len)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
char *name = NULL, *from_ucs = NULL;
|
char *name = NULL, *from_ucs = NULL;
|
||||||
|
|
||||||
if (strcmp(fsdata->local_charset, fsdata->input_charset)) {
|
if (strcmp(fsdata->local_charset, fsdata->input_charset)) {
|
||||||
/* charset conversion needed */
|
/* charset conversion needed */
|
||||||
ret = strnconv(str, fsdata->input_charset, fsdata->local_charset, len,
|
ret = strnconv(str, fsdata->input_charset, fsdata->local_charset, len,
|
||||||
@ -1278,13 +1330,14 @@ char *get_name(_ImageFsData *fsdata, const char *str, size_t len)
|
|||||||
return NULL; /* aborted */
|
return NULL; /* aborted */
|
||||||
}
|
}
|
||||||
/* fallback */
|
/* fallback */
|
||||||
|
ret = make_hopefully_unique_name(fsdata, str, len, &name);
|
||||||
/* >>> create a hopefully unique name */;
|
if (ret == ISO_SUCCESS)
|
||||||
|
return name;
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we reach here when the charset conversion is not needed or has failed */
|
/* we reach here when the charset conversion is not needed */
|
||||||
|
|
||||||
name = malloc(len + 1);
|
name = malloc(len + 1);
|
||||||
if (name == NULL) {
|
if (name == NULL) {
|
||||||
@ -3029,7 +3082,8 @@ int src_aa_to_node(IsoFileSource *src, IsoNode *node, int flag)
|
|||||||
|
|
||||||
static
|
static
|
||||||
int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
||||||
IsoFileSource *src, IsoNode **node)
|
IsoFileSource *src, char *in_name,
|
||||||
|
IsoNode **node)
|
||||||
{
|
{
|
||||||
int ret, idx, to_copy;
|
int ret, idx, to_copy;
|
||||||
struct stat info;
|
struct stat info;
|
||||||
@ -3055,7 +3109,14 @@ int image_builder_create_node(IsoNodeBuilder *builder, IsoImage *image,
|
|||||||
data = (ImageFileSourceData*)src->data;
|
data = (ImageFileSourceData*)src->data;
|
||||||
fsdata = data->fs->data;
|
fsdata = data->fs->data;
|
||||||
|
|
||||||
|
if (in_name == NULL) {
|
||||||
name = iso_file_source_get_name(src);
|
name = iso_file_source_get_name(src);
|
||||||
|
} else {
|
||||||
|
name = strdup(in_name);
|
||||||
|
if (name == NULL) {
|
||||||
|
ret = ISO_OUT_OF_MEM; goto ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* get info about source */
|
/* get info about source */
|
||||||
ret = iso_file_source_lstat(src, &info);
|
ret = iso_file_source_lstat(src, &info);
|
||||||
@ -3518,6 +3579,22 @@ ex:;
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
void issue_collision_warning_summary(size_t failures)
|
||||||
|
{
|
||||||
|
if (failures > ISO_IMPORT_COLL_WARN_MAX) {
|
||||||
|
iso_msg_submit(-1, ISO_IMPORT_COLLISION, 0,
|
||||||
|
"More file name collisions had to be resolved");
|
||||||
|
}
|
||||||
|
if (failures > 0) {
|
||||||
|
iso_msg_submit(-1, ISO_IMPORT_COLLISION, 0,
|
||||||
|
"Sum of resolved file name collisions: %.f",
|
||||||
|
(double) failures);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int iso_image_import(IsoImage *image, IsoDataSource *src,
|
int iso_image_import(IsoImage *image, IsoDataSource *src,
|
||||||
struct iso_read_opts *opts,
|
struct iso_read_opts *opts,
|
||||||
IsoReadImageFeatures **features)
|
IsoReadImageFeatures **features)
|
||||||
@ -3667,6 +3744,7 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
|
|||||||
goto import_revert;
|
goto import_revert;
|
||||||
}
|
}
|
||||||
issue_ucs2_warning_summary(data->joliet_ucs2_failures);
|
issue_ucs2_warning_summary(data->joliet_ucs2_failures);
|
||||||
|
issue_collision_warning_summary(image->collision_warnings);
|
||||||
|
|
||||||
/* Take over inode management from IsoImageFilesystem.
|
/* Take over inode management from IsoImageFilesystem.
|
||||||
data->inode_counter is supposed to hold the maximum PX inode number.
|
data->inode_counter is supposed to hold the maximum PX inode number.
|
||||||
@ -3700,7 +3778,7 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
|
|||||||
goto import_revert;
|
goto import_revert;
|
||||||
}
|
}
|
||||||
ret = image_builder_create_node(image->builder, image, boot_src,
|
ret = image_builder_create_node(image->builder, image, boot_src,
|
||||||
&node);
|
NULL, &node);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
iso_node_builder_unref(image->builder);
|
iso_node_builder_unref(image->builder);
|
||||||
goto import_revert;
|
goto import_revert;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
* Copyright (c) 2009 - 2013 Thomas Schmitt
|
* Copyright (c) 2009 - 2014 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* This file is part of the libisofs project; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License version 2
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -97,6 +97,7 @@ int iso_image_new(const char *name, IsoImage **image)
|
|||||||
img->generator_is_running = 0;
|
img->generator_is_running = 0;
|
||||||
for (i = 0; i < ISO_HFSPLUS_BLESS_MAX; i++)
|
for (i = 0; i < ISO_HFSPLUS_BLESS_MAX; i++)
|
||||||
img->hfsplus_blessed[i] = NULL;
|
img->hfsplus_blessed[i] = NULL;
|
||||||
|
img->collision_warnings = 0;
|
||||||
|
|
||||||
*image = img;
|
*image = img;
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
* Copyright (c) 2009 - 2012 Thomas Schmitt
|
* Copyright (c) 2009 - 2014 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* This file is part of the libisofs project; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License version 2
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -22,6 +22,9 @@
|
|||||||
*/
|
*/
|
||||||
#define ISO_USED_INODE_RANGE (1 << 18)
|
#define ISO_USED_INODE_RANGE (1 << 18)
|
||||||
|
|
||||||
|
/* How many warnings to issue about name collisions during iso_image_import()
|
||||||
|
*/
|
||||||
|
#define ISO_IMPORT_COLL_WARN_MAX 10
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Image is a context for image manipulation.
|
* Image is a context for image manipulation.
|
||||||
@ -196,6 +199,9 @@ struct Iso_Image
|
|||||||
*/
|
*/
|
||||||
IsoNode *hfsplus_blessed[ISO_HFSPLUS_BLESS_MAX];
|
IsoNode *hfsplus_blessed[ISO_HFSPLUS_BLESS_MAX];
|
||||||
|
|
||||||
|
/* Counts the name collisions while iso_image_import() */
|
||||||
|
size_t collision_warnings;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007-2008 Vreixo Formoso, Mario Danic
|
* Copyright (c) 2007-2008 Vreixo Formoso, Mario Danic
|
||||||
* Copyright (c) 2009-2013 Thomas Schmitt
|
* Copyright (c) 2009-2014 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* This file is part of the libisofs project; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License version 2
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -328,7 +328,7 @@ enum eltorito_boot_media_type {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Replace mode used when addding a node to a file.
|
* Replace mode used when addding a node to a directory.
|
||||||
* This controls how libisofs will act when you tried to add to a dir a file
|
* This controls how libisofs will act when you tried to add to a dir a file
|
||||||
* with the same name that an existing file.
|
* with the same name that an existing file.
|
||||||
*
|
*
|
||||||
@ -7605,6 +7605,9 @@ int iso_conv_name_chars(IsoWriteOpts *opts, char *name, size_t name_len,
|
|||||||
/** Filename not suitable for character set UCS-2 (WARNING, HIGH, -397) */
|
/** Filename not suitable for character set UCS-2 (WARNING, HIGH, -397) */
|
||||||
#define ISO_NAME_NOT_UCS2 0xD030FE73
|
#define ISO_NAME_NOT_UCS2 0xD030FE73
|
||||||
|
|
||||||
|
/** File name collision during ISO image import (WARNING, HIGH, -398) */
|
||||||
|
#define ISO_IMPORT_COLLISION 0xD030FE72
|
||||||
|
|
||||||
|
|
||||||
/* Internal developer note:
|
/* Internal developer note:
|
||||||
Place new error codes directly above this comment.
|
Place new error codes directly above this comment.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
* Copyright (c) 2009 - 2011 Thomas Schmitt
|
* Copyright (c) 2009 - 2014 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* This file is part of the libisofs project; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License version 2
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -505,6 +505,8 @@ const char *iso_error_to_msg(int errcode)
|
|||||||
return "Unrecognized file type in ISO image";
|
return "Unrecognized file type in ISO image";
|
||||||
case ISO_NAME_NOT_UCS2:
|
case ISO_NAME_NOT_UCS2:
|
||||||
return "Filename not suitable for character set UCS-2";
|
return "Filename not suitable for character set UCS-2";
|
||||||
|
case ISO_IMPORT_COLLISION:
|
||||||
|
return "File name collision during ISO image import";
|
||||||
default:
|
default:
|
||||||
return "Unknown error";
|
return "Unknown error";
|
||||||
}
|
}
|
||||||
|
156
libisofs/tree.c
156
libisofs/tree.c
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Vreixo Formoso
|
* Copyright (c) 2007 Vreixo Formoso
|
||||||
* Copyright (c) 2011 Thomas Schmitt
|
* Copyright (c) 2011 - 2014 Thomas Schmitt
|
||||||
*
|
*
|
||||||
* This file is part of the libisofs project; you can redistribute it and/or
|
* This file is part of the libisofs project; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License version 2
|
* modify it under the terms of the GNU General Public License version 2
|
||||||
@ -23,6 +23,7 @@
|
|||||||
#include "builder.h"
|
#include "builder.h"
|
||||||
#include "messages.h"
|
#include "messages.h"
|
||||||
#include "tree.h"
|
#include "tree.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -521,7 +522,7 @@ int iso_tree_add_node_builder(IsoImage *image, IsoDir *parent,
|
|||||||
return ISO_NODE_NAME_NOT_UNIQUE;
|
return ISO_NODE_NAME_NOT_UNIQUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = builder->create_node(builder, image, src, &new);
|
result = builder->create_node(builder, image, src, name, &new);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -587,7 +588,8 @@ int iso_tree_add_new_node(IsoImage *image, IsoDir *parent, const char *name,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = image->builder->create_node(image->builder, image, file, &new);
|
result = image->builder->create_node(image->builder, image, file,
|
||||||
|
(char *) name, &new);
|
||||||
|
|
||||||
/* free the file */
|
/* free the file */
|
||||||
iso_file_source_unref(file);
|
iso_file_source_unref(file);
|
||||||
@ -596,12 +598,6 @@ int iso_tree_add_new_node(IsoImage *image, IsoDir *parent, const char *name,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = iso_node_set_name(new, name);
|
|
||||||
if (result < 0) {
|
|
||||||
iso_node_unref(new);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (node) {
|
if (node) {
|
||||||
*node = new;
|
*node = new;
|
||||||
}
|
}
|
||||||
@ -742,6 +738,97 @@ int check_special(IsoImage *image, mode_t mode)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
void ascii_increment(char *name, int pos)
|
||||||
|
{
|
||||||
|
int c, len;
|
||||||
|
|
||||||
|
len = strlen(name);
|
||||||
|
if (pos < 0 || pos >= len)
|
||||||
|
pos = len - 1;
|
||||||
|
c = name[pos];
|
||||||
|
if (c >= '0' && c < '9') {
|
||||||
|
c++;
|
||||||
|
} else if (c == '9') {
|
||||||
|
c = 'A';
|
||||||
|
} else if (c >= 'A' && c < 'Z') {
|
||||||
|
c++;
|
||||||
|
} else if (c == 'Z') {
|
||||||
|
c = '_';
|
||||||
|
} else if (c == '_') {
|
||||||
|
c = 'a';
|
||||||
|
} else if (c >= 'a' && c < 'z') {
|
||||||
|
c++;
|
||||||
|
} else if (c == 'z') {
|
||||||
|
c = '0';
|
||||||
|
name[pos] = c;
|
||||||
|
ascii_increment(name, pos - 1);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
if (pos == len - 1 || name[pos + 1] == '.')
|
||||||
|
c = '_'; /* Make first change less riddling */
|
||||||
|
else
|
||||||
|
c = '0'; /* But else use the full range of valid characters */
|
||||||
|
}
|
||||||
|
name[pos] = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
int make_really_unique_name(IsoDir *parent, char **name, char **unique_name,
|
||||||
|
IsoNode ***pos, int flag)
|
||||||
|
{
|
||||||
|
int len, ret, pre_check = 0, ascii_idx = -1, first;
|
||||||
|
char *dpt;
|
||||||
|
|
||||||
|
len = strlen(*name);
|
||||||
|
if (len < 8) {
|
||||||
|
/* Insert underscores before last dot */
|
||||||
|
LIBISO_ALLOC_MEM(*unique_name, char, 8 + 1);
|
||||||
|
first = len;
|
||||||
|
dpt = strrchr(*name, '.');
|
||||||
|
if (dpt != NULL)
|
||||||
|
first = (dpt - *name);
|
||||||
|
if (first > 0)
|
||||||
|
memcpy(*unique_name, *name, first);
|
||||||
|
memset(*unique_name + first, '_', 8 - len);
|
||||||
|
if (len > 0)
|
||||||
|
memcpy(*unique_name + (8 - (len - first)), *name + first,
|
||||||
|
len - first);
|
||||||
|
len = 8;
|
||||||
|
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) {
|
||||||
|
if (!pre_check)
|
||||||
|
ascii_increment(*unique_name, ascii_idx);
|
||||||
|
else
|
||||||
|
pre_check = 0;
|
||||||
|
ret = iso_dir_exists(parent, *unique_name, pos);
|
||||||
|
if (ret < 0)
|
||||||
|
goto ex;
|
||||||
|
if (ret == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*name = *unique_name;
|
||||||
|
ret = ISO_SUCCESS;
|
||||||
|
ex:;
|
||||||
|
if (ret < 0) {
|
||||||
|
LIBISO_FREE_MEM(*unique_name);
|
||||||
|
*unique_name = NULL;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Recursively add a given directory to the image tree.
|
* Recursively add a given directory to the image tree.
|
||||||
*
|
*
|
||||||
@ -750,12 +837,12 @@ int check_special(IsoImage *image, mode_t mode)
|
|||||||
*/
|
*/
|
||||||
int iso_add_dir_src_rec(IsoImage *image, IsoDir *parent, IsoFileSource *dir)
|
int iso_add_dir_src_rec(IsoImage *image, IsoDir *parent, IsoFileSource *dir)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret, dir_is_open = 0;
|
||||||
IsoNodeBuilder *builder;
|
IsoNodeBuilder *builder;
|
||||||
IsoFileSource *file;
|
IsoFileSource *file;
|
||||||
IsoNode **pos;
|
IsoNode **pos;
|
||||||
struct stat info;
|
struct stat info;
|
||||||
char *name, *path;
|
char *name, *path, *allocated_name = NULL;
|
||||||
IsoNode *new;
|
IsoNode *new;
|
||||||
enum iso_replace_mode replace;
|
enum iso_replace_mode replace;
|
||||||
|
|
||||||
@ -771,8 +858,9 @@ int iso_add_dir_src_rec(IsoImage *image, IsoDir *parent, IsoFileSource *dir)
|
|||||||
ret = iso_msg_submit(image->id, ISO_NULL_POINTER, ret,
|
ret = iso_msg_submit(image->id, ISO_NULL_POINTER, ret,
|
||||||
"Can't open dir. NULL pointer caught as dir name");
|
"Can't open dir. NULL pointer caught as dir name");
|
||||||
}
|
}
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
|
dir_is_open = 1;
|
||||||
|
|
||||||
builder = image->builder;
|
builder = image->builder;
|
||||||
|
|
||||||
@ -785,15 +873,16 @@ int iso_add_dir_src_rec(IsoImage *image, IsoDir *parent, IsoFileSource *dir)
|
|||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
/* error reading dir */
|
/* error reading dir */
|
||||||
ret = iso_msg_submit(image->id, ret, ret, "Error reading dir");
|
ret = iso_msg_submit(image->id, ret, ret, "Error reading dir");
|
||||||
|
goto ex;
|
||||||
}
|
}
|
||||||
break;
|
break; /* End of directory */
|
||||||
}
|
}
|
||||||
|
|
||||||
path = iso_file_source_get_path(file);
|
path = iso_file_source_get_path(file);
|
||||||
if (path == NULL) {
|
if (path == NULL) {
|
||||||
ret = iso_msg_submit(image->id, ISO_NULL_POINTER, ret,
|
ret = iso_msg_submit(image->id, ISO_NULL_POINTER, ret,
|
||||||
"NULL pointer caught as file path");
|
"NULL pointer caught as file path");
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
name = strrchr(path, '/') + 1;
|
name = strrchr(path, '/') + 1;
|
||||||
|
|
||||||
@ -827,17 +916,23 @@ int iso_add_dir_src_rec(IsoImage *image, IsoDir *parent, IsoFileSource *dir)
|
|||||||
|
|
||||||
/* find place where to insert */
|
/* find place where to insert */
|
||||||
ret = iso_dir_exists(parent, name, &pos);
|
ret = iso_dir_exists(parent, name, &pos);
|
||||||
/* TODO
|
if (ret) {
|
||||||
* if (ret && replace == ISO_REPLACE_ASK) {
|
/* Resolve name collision
|
||||||
* replace = /....
|
e.g. caused by fs_image.c:make_hopefully_unique_name()
|
||||||
* }
|
|
||||||
*/
|
*/
|
||||||
|
LIBISO_FREE_MEM(allocated_name); allocated_name = NULL;
|
||||||
/* chek if we must insert or not */
|
ret = make_really_unique_name(parent, &name, &allocated_name, &pos,
|
||||||
/* TODO check for other replace behavior */
|
0);
|
||||||
if (ret && (replace == ISO_REPLACE_NEVER)) {
|
if (ret < 0)
|
||||||
/* skip file */
|
goto ex;
|
||||||
goto dir_rec_continue;
|
image->collision_warnings++;
|
||||||
|
if (image->collision_warnings < ISO_IMPORT_COLL_WARN_MAX) {
|
||||||
|
ret = iso_msg_submit(image->id, ISO_IMPORT_COLLISION, 0,
|
||||||
|
"File name collision resolved with %s . Now: %s",
|
||||||
|
path, name);
|
||||||
|
if (ret < 0)
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if we are here we must insert. Give user a chance for cancel */
|
/* if we are here we must insert. Give user a chance for cancel */
|
||||||
@ -848,7 +943,7 @@ int iso_add_dir_src_rec(IsoImage *image, IsoDir *parent, IsoFileSource *dir)
|
|||||||
goto dir_rec_continue;
|
goto dir_rec_continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ret = builder->create_node(builder, image, file, &new);
|
ret = builder->create_node(builder, image, file, name, &new);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
ret = iso_msg_submit(image->id, ISO_FILE_CANT_ADD, ret,
|
ret = iso_msg_submit(image->id, ISO_FILE_CANT_ADD, ret,
|
||||||
"Error when adding file %s", path);
|
"Error when adding file %s", path);
|
||||||
@ -884,14 +979,17 @@ dir_rec_continue:;
|
|||||||
/* check for error severity to decide what to do */
|
/* check for error severity to decide what to do */
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
ret = iso_msg_submit(image->id, ret, 0, NULL);
|
ret = iso_msg_submit(image->id, ret, 0, NULL);
|
||||||
if (ret < 0) {
|
if (ret < 0)
|
||||||
break;
|
goto ex;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} /* while */
|
} /* while */
|
||||||
|
|
||||||
|
ret = ISO_SUCCESS;
|
||||||
|
ex:;
|
||||||
|
if (dir_is_open)
|
||||||
iso_file_source_close(dir);
|
iso_file_source_close(dir);
|
||||||
return ret < 0 ? ret : ISO_SUCCESS;
|
LIBISO_FREE_MEM(allocated_name);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int iso_tree_add_dir_rec(IsoImage *image, IsoDir *parent, const char *dir)
|
int iso_tree_add_dir_rec(IsoImage *image, IsoDir *parent, const char *dir)
|
||||||
|
Loading…
Reference in New Issue
Block a user