Skip to content

Commit

Permalink
Support archive files with same name
Browse files Browse the repository at this point in the history
  • Loading branch information
杨赫然 committed Sep 23, 2024
1 parent 4adceee commit 8ea9034
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 21 deletions.
15 changes: 15 additions & 0 deletions common/seaf-utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -459,3 +459,18 @@ seaf_parse_auth_token (const char *auth_token)
g_strfreev (parts);
return token;
}

void
split_filename (const char *filename, char **name, char **ext)
{
char *dot;

dot = strrchr (filename, '.');
if (dot) {
*ext = g_strdup (dot + 1);
*name = g_strndup (filename, dot - filename);
} else {
*name = g_strdup (filename);
*ext = NULL;
}
}
3 changes: 3 additions & 0 deletions common/seaf-utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,7 @@ seaf_gen_notif_server_jwt (const char *repo_id, const char *username);
char *
seaf_parse_auth_token (const char *auth_token);

void
split_filename (const char *filename, char **name, char **ext);

#endif
63 changes: 57 additions & 6 deletions server/pack-dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

#include "seafile-session.h"
#include "pack-dir.h"
#include "seaf-utils.h"

#include <archive.h>
#include <archive_entry.h>
Expand Down Expand Up @@ -67,6 +68,7 @@ do_iconv (char *fromcode, char *tocode, char *in)
static int
add_file_to_archive (PackDirData *data,
const char *parent_dir,
const char *base_name,
SeafDirent *dent)
{
struct archive *a = data->a;
Expand All @@ -91,7 +93,7 @@ add_file_to_archive (PackDirData *data,
int dec_out_len = -1;
int ret = 0;

pathname = g_build_filename (top_dir_name, parent_dir, dent->name, NULL);
pathname = g_build_filename (top_dir_name, parent_dir, base_name, NULL);

file = seaf_fs_manager_get_seafile (seaf->fs_mgr,
data->store_id, data->repo_version,
Expand Down Expand Up @@ -332,15 +334,15 @@ archive_dir (PackDirData *data,

dent = ptr->data;
if (S_ISREG(dent->mode)) {
ret = add_file_to_archive (data, dirpath, dent);
ret = add_file_to_archive (data, dirpath, dent->name, dent);
if (ret == 0) {
g_atomic_int_inc (&progress->zipped);
}
} else if (S_ISLNK(dent->mode)) {
if (archive_version_number() >= 3000001) {
/* Symlink in zip arhive is not supported in earlier version
* of libarchive */
ret = add_file_to_archive (data, dirpath, dent);
ret = add_file_to_archive (data, dirpath, dent->name, dent);
}

} else if (S_ISDIR(dent->mode)) {
Expand Down Expand Up @@ -401,31 +403,80 @@ pack_dir_data_new (const char *store_id,
return data;
}

static gboolean
name_exists (GList *file_list, const char *filename)
{
GList *ptr;
char *name;

for (ptr = file_list; ptr != NULL; ptr = ptr->next) {
name = ptr->data;
if (strcmp (name, filename) == 0)
return TRUE;
}

return FALSE;
}

static char *
generate_unique_filename (const char *file, GList *file_list)
{
int i = 1;
char *name, *ext, *unique_name;

unique_name = g_strdup(file);
split_filename (unique_name, &name, &ext);
while (name_exists (file_list, unique_name)) {
g_free (unique_name);
if (ext)
unique_name = g_strdup_printf ("%s (%d).%s", name, i, ext);
else
unique_name = g_strdup_printf ("%s (%d)", name, i);
i++;
}

g_free (name);
g_free (ext);

return unique_name;
}

static int
archive_multi (PackDirData *data, GList *dirent_list,
Progress *progress)
{
GList *iter;
SeafDirent *dirent;
GList *file_list = NULL;

for (iter = dirent_list; iter; iter = iter->next) {
if (progress->canceled)
char *unique_name = NULL;
if (progress->canceled) {
string_list_free (file_list);
return -1;
}
dirent = iter->data;
if (S_ISREG(dirent->mode)) {
if (add_file_to_archive (data, "", dirent) < 0) {
unique_name = generate_unique_filename (dirent->name, file_list);
file_list = g_list_prepend (file_list, unique_name);
if (add_file_to_archive (data, "", unique_name, dirent) < 0) {
string_list_free (file_list);
seaf_warning ("Failed to archive file: %s.\n", dirent->name);
return -1;
}
g_atomic_int_inc (&progress->zipped);
} else if (S_ISDIR(dirent->mode)) {
if (archive_dir (data, dirent->id, dirent->name, progress) < 0) {
unique_name = generate_unique_filename (dirent->name, file_list);
file_list = g_list_prepend (file_list, unique_name);
if (archive_dir (data, dirent->id, unique_name, progress) < 0) {
string_list_free (file_list);
seaf_warning ("Failed to archive dir: %s.\n", dirent->name);
return -1;
}
}
}

string_list_free (file_list);
return 0;
}

Expand Down
16 changes: 1 addition & 15 deletions server/repo-op.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "diff-simple.h"
#include "merge-new.h"
#include "change-set.h"
#include "seaf-utils.h"

#include "seaf-db.h"

Expand Down Expand Up @@ -97,21 +98,6 @@ filename_exists (GList *entries, const char *filename)
return FALSE;
}

static void
split_filename (const char *filename, char **name, char **ext)
{
char *dot;

dot = strrchr (filename, '.');
if (dot) {
*ext = g_strdup (dot + 1);
*name = g_strndup (filename, dot - filename);
} else {
*name = g_strdup (filename);
*ext = NULL;
}
}

static char *
generate_unique_filename (const char *file, GList *entries)
{
Expand Down

0 comments on commit 8ea9034

Please sign in to comment.