Skip to content

Commit

Permalink
Merge pull request torvalds#294 from copumpkin/cptofs-symlinks
Browse files Browse the repository at this point in the history
lkl tools: add symlink support to cptofs
  • Loading branch information
tavip authored Jan 16, 2017
2 parents 3472d83 + c22fee9 commit 6c7ad3e
Showing 1 changed file with 89 additions and 6 deletions.
95 changes: 89 additions & 6 deletions tools/lkl/cptofs.c
Original file line number Diff line number Diff line change
Expand Up @@ -236,20 +236,28 @@ static int copy_file(const char *src, const char *dst, int mode)
return ret;
}

static int stat_src(const char *path, int *type, int *mode)
static int stat_src(const char *path, int *type, int *mode, int *size)
{
struct stat stat;
struct lkl_stat lkl_stat;
int ret;

if (cptofs) {
ret = lstat(path, &stat);
*type = stat.st_mode & S_IFMT;
*mode = stat.st_mode & ~S_IFMT;
if (type)
*type = stat.st_mode & S_IFMT;
if (mode)
*mode = stat.st_mode & ~S_IFMT;
if (size)
*size = stat.st_size;
} else {
ret = lkl_sys_lstat(path, &lkl_stat);
*type = lkl_stat.st_mode & S_IFMT;
*mode = lkl_stat.st_mode & ~S_IFMT;
if (type)
*type = lkl_stat.st_mode & S_IFMT;
if (mode)
*mode = lkl_stat.st_mode & ~S_IFMT;
if (size)
*size = lkl_stat.st_size;
}

if (ret)
Expand Down Expand Up @@ -280,6 +288,79 @@ static int mkdir_dst(const char *path, int mode)
return ret;
}

static int readlink_src(const char *src, char *out, int outsize)
{
int ret;

if (cptofs)
ret = readlink(src, out, outsize);
else
ret = lkl_sys_readlink(src, out, outsize);

if (ret < 0)
fprintf(stderr, "unable to readlink '%s': %s\n", src,
cptofs ? strerror(errno) : lkl_strerror(ret));

return ret;
}

static int symlink_dst(const char *path, const char *target)
{
int ret;

if (cptofs)
ret = lkl_sys_symlink(target, path);
else
ret = symlink(target, path);

if (ret)
fprintf(stderr, "unable to symlink '%s' with target '%s': %s\n",
path, target, cptofs ? lkl_strerror(ret) :
strerror(errno));

return ret;
}

static int copy_symlink(const char *src, const char *dst)
{
int ret;
int size;
char *target = NULL;

ret = stat_src(src, NULL, NULL, &size);
if (ret) {
ret = -1;
goto out;
}

target = malloc(size + 1);
if (!target) {
fprintf(stderr, "Unable to allocate memory (%d bytes)\n",
size + 1);
ret = -1;
goto out;
}

ret = readlink_src(src, target, size);
if (ret != size) {
fprintf(stderr, "readlink(%s) bad size: got %d, expected %d\n",
src, ret, size);
ret = -1;
goto out;
}
target[size] = 0; // readlink doesn't append the trailing null byte

ret = symlink_dst(dst, target);
if (ret)
ret = -1;

out:
if (target)
free(target);

return ret;
}

static int do_entry(const char *_src, const char *_dst, const char *name)
{
char src[PATH_MAX], dst[PATH_MAX];
Expand All @@ -289,7 +370,7 @@ static int do_entry(const char *_src, const char *_dst, const char *name)
snprintf(src, sizeof(src), "%s/%s", _src, name);
snprintf(dst, sizeof(dst), "%s/%s", _dst, name);

ret = stat_src(src, &type, &mode);
ret = stat_src(src, &type, &mode, NULL);

switch (type) {
case S_IFREG:
Expand All @@ -304,6 +385,8 @@ static int do_entry(const char *_src, const char *_dst, const char *name)
ret = searchdir(src, dst, NULL);
break;
case S_IFLNK:
ret = copy_symlink(src, dst);
break;
case S_IFSOCK:
case S_IFBLK:
case S_IFCHR:
Expand Down

0 comments on commit 6c7ad3e

Please sign in to comment.