diff options
author | Martin Matuska <martin@matuska.org> | 2019-04-15 01:50:29 +0200 |
---|---|---|
committer | Martin Matuska <martin@matuska.org> | 2019-04-15 23:36:06 +0200 |
commit | b0ed582e68fe6e474d321934d29b0f229c0feb9f (patch) | |
tree | 04d67b7fa3d5631736f850a1aead1dbe88e4f30a /libarchive/archive_write_disk_windows.c | |
parent | 19bd077987ff26a4cb108edde5eaf970837aa1f0 (diff) | |
download | libarchive-b0ed582e68fe6e474d321934d29b0f229c0feb9f.tar.gz |
Windows symlinks: new functions and extended tar header
New functions:
archive_entry_symlink_type()
archive_entry_set_symlink_type()
Suppoted value constants:
AE_SYMLINK_TYPE_UNDEFINED
AE_SYMLINK_TYPE_FILE
AE_SYMLINK_TYPE_DIRECTORY
New extended tar header:
LIBARCHIVE.symlinktype
The function archive_entry_symlink_type() retrieves and the function
archive_entry_set_symlink_type() sets the symbolic link type of an archive
entry. The information about the symbolic link type is required to properly
restore symbolic links on Microsoft Windows. If the symlink type is set
to AE_SYMLINK_TYPE_FILE or AE_SYMLINK_TYPE_DIRECTORY and a tar archive
is written, an extended tar header LIBARCHIVE.symlinktype is stored with
the value "file" or "dir". When reading symbolic links on Windows, the
link type is automatically stored in the archive_entry structure.
On unix systems, the symlink type has no effect when reading or writing
symbolic links.
Diffstat (limited to 'libarchive/archive_write_disk_windows.c')
-rw-r--r-- | libarchive/archive_write_disk_windows.c | 24 |
1 files changed, 14 insertions, 10 deletions
diff --git a/libarchive/archive_write_disk_windows.c b/libarchive/archive_write_disk_windows.c index b29389c1..e3e65ba1 100644 --- a/libarchive/archive_write_disk_windows.c +++ b/libarchive/archive_write_disk_windows.c @@ -587,13 +587,14 @@ la_CreateHardLinkW(wchar_t *linkname, wchar_t *target) } /* - * Create symolic link + * Create file or directory symolic link * - * Always creates a file symbolic link. - * Directory symbolic links are currently not implemented. + * If linktype is AE_SYMLINK_TYPE_UNDEFINED (or unknown), guess linktype from + * the link target */ static int -la_CreateSymbolicLinkW(const wchar_t *linkname, const wchar_t *target) { +la_CreateSymbolicLinkW(const wchar_t *linkname, const wchar_t *target, + int linktype) { static BOOLEAN (WINAPI *f)(LPCWSTR, LPCWSTR, DWORD); static int set; wchar_t *ttarget, *p; @@ -636,14 +637,16 @@ la_CreateSymbolicLinkW(const wchar_t *linkname, const wchar_t *target) { *p = L'\0'; /* + * In case of undefined symlink type we guess it from the target. * If the target equals ".", "..", ends with a backslash or a - * backslash followed by "." or ".." it always points to a directory. - * In this case we can safely set the directory flag. - * All other symlinks are created as file symlinks. + * backslash followed by "." or ".." we assume it is a directory + * symlink. In all other cases we assume a file symlink. */ - if (*(p - 1) == L'\\' || (*(p - 1) == L'.' && ( + if (linktype != AE_SYMLINK_TYPE_FILE && ( + linktype == AE_SYMLINK_TYPE_DIRECTORY || + *(p - 1) == L'\\' || (*(p - 1) == L'.' && ( len == 1 || *(p - 2) == L'\\' || ( *(p - 2) == L'.' && ( - len == 2 || *(p - 3) == L'\\'))))) { + len == 2 || *(p - 3) == L'\\')))))) { #if defined(SYMBOLIC_LINK_FLAG_DIRECTORY) flags |= SYMBOLIC_LINK_FLAG_DIRECTORY; #else @@ -1638,7 +1641,8 @@ create_filesystem_object(struct archive_write_disk *a) return symlink(linkname, a->name) ? errno : 0; #else errno = 0; - r = la_CreateSymbolicLinkW((const wchar_t *)a->name, linkname); + r = la_CreateSymbolicLinkW((const wchar_t *)a->name, linkname, + archive_entry_symlink_type(a->entry)); if (r == 0) { if (errno == 0) la_dosmaperr(GetLastError()); |