-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathandroid.patch
115 lines (112 loc) · 3.64 KB
/
android.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
--- libarchive/archive_string.c
+++ libarchive/archive_string.c
@@ -59,6 +59,8 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_string.c 201095 2009-12-28 02:33
#endif
#if defined(_WIN32) && !defined(__CYGWIN__)
#include <windows.h>
+#endif
+#if defined(_WIN32) && !defined(__CYGWIN__) || defined(HAVE_LOCALE_H)
#include <locale.h>
#endif
@@ -429,9 +431,21 @@ default_iconv_charset(const char *charset) {
return locale_charset();
#elif HAVE_NL_LANGINFO
return nl_langinfo(CODESET);
+#else
+ // No iconv, etc... :(
+#if defined(HAVE_SETLOCALE)
+ // It is required just to understand what can we actually convert...
+ const char *const locale = setlocale(LC_CTYPE, NULL);
+ const char *const dot = strchr(locale, '.');
+ if (dot != NULL)
+ return dot + 1;
+#endif
+#if defined(__ANDROID__)
+ return "UTF-8"; // It looks a bit more sane here...
#else
return "";
#endif
+#endif
}
#if defined(_WIN32) && !defined(__CYGWIN__)
--- libarchive/archive_write_disk_posix.c
+++ libarchive/archive_write_disk_posix.c
@@ -2206,8 +2206,8 @@ restore_entry(struct archive_write_disk *a)
if (en) {
/* Everything failed; give up here. */
if ((&a->archive)->error == NULL)
- archive_set_error(&a->archive, en, "Can't create '%s'",
- a->name);
+ archive_set_error(&a->archive, en, "Can't create '%s', errno = %d",
+ a->name, en);
return (ARCHIVE_FAILED);
}
@@ -2237,13 +2237,13 @@ create_filesystem_object(struct archive_write_disk *a)
/* Since link(2) and symlink(2) don't handle modes, we're done here. */
linkname = archive_entry_hardlink(a->entry);
if (linkname != NULL) {
-#if !HAVE_LINK
+#if !(HAVE_LINK || (defined(IS_ANDROID_NOROOT) && HAVE_SYMLINK))
return (EPERM);
#else
archive_string_init(&error_string);
linkname_copy = strdup(linkname);
if (linkname_copy == NULL) {
- return (EPERM);
+ return (ENOMEM);
}
/*
* TODO: consider using the cleaned-up path as the link
@@ -2284,12 +2284,39 @@ create_filesystem_object(struct archive_write_disk *a)
*/
if (a->flags & ARCHIVE_EXTRACT_SAFE_WRITES)
unlink(a->name);
+#ifndef IS_ANDROID_NOROOT
#ifdef HAVE_LINKAT
r = linkat(AT_FDCWD, linkname, AT_FDCWD, a->name,
0) ? errno : 0;
#else
r = link(linkname, a->name) ? errno : 0;
#endif
+ if (r != 0)
+ archive_set_error(&a->archive, ARCHIVE_FAILED, "Can't create hard link '%s', errno = %d",
+ a->name, r);
+#else /* IS_ANDROID_NOROOT */
+/*
+ * Nonrooted Android can't do hard links!
+ * Just pretend they are symlinks.
+ * Let's treat the archive root as a chroot root for now.
+ * TODO: Fix this temporary solution later.
+ */
+ if (linkname[0] != '/') {
+ if (linkname[0] == '.' && linkname[1] == '/') {
+ r = symlink(linkname + 1, a->name) ? errno : 0;
+ } else {
+ char _linkname[strlen(linkname) + 2];
+ _linkname[0] = '/';
+ strcpy(_linkname + 1, linkname);
+ r = symlink(_linkname, a->name) ? errno : 0;
+ }
+ } else {
+ r = symlink(linkname, a->name) ? errno : 0;
+ }
+ if (r != 0)
+ archive_set_error(&a->archive, ARCHIVE_FAILED, "Can't create a symlink substitution of the hardlink '%s', errno = %d",
+ a->name, r);
+#endif /* IS_ANDROID_NOROOT */
/*
* New cpio and pax formats allow hardlink entries
* to carry data, so we may have to open the file
@@ -2334,7 +2361,11 @@ create_filesystem_object(struct archive_write_disk *a)
*/
if (a->flags & ARCHIVE_EXTRACT_SAFE_WRITES)
unlink(a->name);
- return symlink(linkname, a->name) ? errno : 0;
+ r = symlink(linkname, a->name) ? errno : 0;
+ if (r != 0)
+ archive_set_error(&a->archive, ARCHIVE_FAILED, "Can't create symlink '%s', errno = %d",
+ a->name, r);
+ return (r);
#else
return (EPERM);
#endif