/src/systemd/src/shared/libarchive-util.c
Line | Count | Source |
1 | | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
2 | | |
3 | | #include <syslog.h> |
4 | | |
5 | | #include "libarchive-util.h" |
6 | | #include "log.h" /* IWYU pragma: keep */ |
7 | | #include "user-util.h" /* IWYU pragma: keep */ |
8 | | |
9 | | #if HAVE_LIBARCHIVE |
10 | | DLSYM_PROTOTYPE(archive_entry_acl_add_entry) = NULL; |
11 | | DLSYM_PROTOTYPE(archive_entry_acl_next) = NULL; |
12 | | DLSYM_PROTOTYPE(archive_entry_acl_reset) = NULL; |
13 | | DLSYM_PROTOTYPE(archive_entry_fflags) = NULL; |
14 | | DLSYM_PROTOTYPE(archive_entry_filetype) = NULL; |
15 | | DLSYM_PROTOTYPE(archive_entry_free) = NULL; |
16 | | DLSYM_PROTOTYPE(archive_entry_gid) = NULL; |
17 | | static int missing_archive_entry_gid_is_set(struct archive_entry *e) { |
18 | | return gid_is_valid(sym_archive_entry_gid(e)); |
19 | | } |
20 | | DLSYM_PROTOTYPE(archive_entry_gid_is_set) = missing_archive_entry_gid_is_set; |
21 | | DLSYM_PROTOTYPE(archive_entry_hardlink) = NULL; |
22 | | static int missing_archive_entry_hardlink_is_set(struct archive_entry *e) { |
23 | | return !!sym_archive_entry_hardlink(e); |
24 | | } |
25 | | DLSYM_PROTOTYPE(archive_entry_hardlink_is_set) = missing_archive_entry_hardlink_is_set; |
26 | | DLSYM_PROTOTYPE(archive_entry_mode) = NULL; |
27 | | DLSYM_PROTOTYPE(archive_entry_mtime) = NULL; |
28 | | DLSYM_PROTOTYPE(archive_entry_mtime_is_set) = NULL; |
29 | | DLSYM_PROTOTYPE(archive_entry_mtime_nsec) = NULL; |
30 | | DLSYM_PROTOTYPE(archive_entry_new) = NULL; |
31 | | DLSYM_PROTOTYPE(archive_entry_pathname) = NULL; |
32 | | DLSYM_PROTOTYPE(archive_entry_rdevmajor) = NULL; |
33 | | DLSYM_PROTOTYPE(archive_entry_rdevminor) = NULL; |
34 | | DLSYM_PROTOTYPE(archive_entry_set_ctime) = NULL; |
35 | | DLSYM_PROTOTYPE(archive_entry_set_fflags) = NULL; |
36 | | DLSYM_PROTOTYPE(archive_entry_set_filetype) = NULL; |
37 | | DLSYM_PROTOTYPE(archive_entry_set_gid) = NULL; |
38 | | DLSYM_PROTOTYPE(archive_entry_set_hardlink) = NULL; |
39 | | DLSYM_PROTOTYPE(archive_entry_set_mtime) = NULL; |
40 | | DLSYM_PROTOTYPE(archive_entry_set_pathname) = NULL; |
41 | | DLSYM_PROTOTYPE(archive_entry_set_perm) = NULL; |
42 | | DLSYM_PROTOTYPE(archive_entry_set_rdevmajor) = NULL; |
43 | | DLSYM_PROTOTYPE(archive_entry_set_rdevminor) = NULL; |
44 | | DLSYM_PROTOTYPE(archive_entry_set_size) = NULL; |
45 | | DLSYM_PROTOTYPE(archive_entry_set_symlink) = NULL; |
46 | | DLSYM_PROTOTYPE(archive_entry_set_uid) = NULL; |
47 | | DLSYM_PROTOTYPE(archive_entry_sparse_add_entry) = NULL; |
48 | | DLSYM_PROTOTYPE(archive_entry_symlink) = NULL; |
49 | | DLSYM_PROTOTYPE(archive_entry_uid) = NULL; |
50 | | static int missing_archive_entry_uid_is_set(struct archive_entry *e) { |
51 | | return uid_is_valid(sym_archive_entry_uid(e)); |
52 | | } |
53 | | DLSYM_PROTOTYPE(archive_entry_uid_is_set) = missing_archive_entry_uid_is_set; |
54 | | DLSYM_PROTOTYPE(archive_entry_xattr_add_entry) = NULL; |
55 | | DLSYM_PROTOTYPE(archive_entry_xattr_next) = NULL; |
56 | | DLSYM_PROTOTYPE(archive_entry_xattr_reset) = NULL; |
57 | | DLSYM_PROTOTYPE(archive_error_string) = NULL; |
58 | | DLSYM_PROTOTYPE(archive_read_data_into_fd) = NULL; |
59 | | DLSYM_PROTOTYPE(archive_read_free) = NULL; |
60 | | DLSYM_PROTOTYPE(archive_read_new) = NULL; |
61 | | DLSYM_PROTOTYPE(archive_read_next_header) = NULL; |
62 | | DLSYM_PROTOTYPE(archive_read_open_fd) = NULL; |
63 | | DLSYM_PROTOTYPE(archive_read_support_format_cpio) = NULL; |
64 | | DLSYM_PROTOTYPE(archive_read_support_format_tar) = NULL; |
65 | | DLSYM_PROTOTYPE(archive_write_close) = NULL; |
66 | | DLSYM_PROTOTYPE(archive_write_data) = NULL; |
67 | | DLSYM_PROTOTYPE(archive_write_free) = NULL; |
68 | | DLSYM_PROTOTYPE(archive_write_header) = NULL; |
69 | | DLSYM_PROTOTYPE(archive_write_new) = NULL; |
70 | | DLSYM_PROTOTYPE(archive_write_open_FILE) = NULL; |
71 | | DLSYM_PROTOTYPE(archive_write_open_fd) = NULL; |
72 | | DLSYM_PROTOTYPE(archive_write_set_format_filter_by_ext) = NULL; |
73 | | DLSYM_PROTOTYPE(archive_write_set_format_pax) = NULL; |
74 | | #endif |
75 | | |
76 | 0 | int dlopen_libarchive(int log_level) { |
77 | | #if HAVE_LIBARCHIVE |
78 | | static void *libarchive_dl = NULL; |
79 | | int r; |
80 | | |
81 | | LIBARCHIVE_NOTE(suggested); |
82 | | |
83 | | r = dlopen_many_sym_or_warn( |
84 | | &libarchive_dl, |
85 | | "libarchive.so.13", |
86 | | log_level, |
87 | | DLSYM_ARG(archive_entry_acl_add_entry), |
88 | | DLSYM_ARG(archive_entry_acl_next), |
89 | | DLSYM_ARG(archive_entry_acl_reset), |
90 | | DLSYM_ARG(archive_entry_fflags), |
91 | | DLSYM_ARG(archive_entry_filetype), |
92 | | DLSYM_ARG(archive_entry_free), |
93 | | DLSYM_ARG(archive_entry_gid), |
94 | | DLSYM_ARG(archive_entry_hardlink), |
95 | | DLSYM_ARG(archive_entry_mode), |
96 | | DLSYM_ARG(archive_entry_mtime), |
97 | | DLSYM_ARG(archive_entry_mtime_is_set), |
98 | | DLSYM_ARG(archive_entry_mtime_nsec), |
99 | | DLSYM_ARG(archive_entry_new), |
100 | | DLSYM_ARG(archive_entry_pathname), |
101 | | DLSYM_ARG(archive_entry_rdevmajor), |
102 | | DLSYM_ARG(archive_entry_rdevminor), |
103 | | DLSYM_ARG(archive_entry_set_ctime), |
104 | | DLSYM_ARG(archive_entry_set_fflags), |
105 | | DLSYM_ARG(archive_entry_set_filetype), |
106 | | DLSYM_ARG(archive_entry_set_gid), |
107 | | DLSYM_ARG(archive_entry_set_hardlink), |
108 | | DLSYM_ARG(archive_entry_set_mtime), |
109 | | DLSYM_ARG(archive_entry_set_pathname), |
110 | | DLSYM_ARG(archive_entry_set_perm), |
111 | | DLSYM_ARG(archive_entry_set_rdevmajor), |
112 | | DLSYM_ARG(archive_entry_set_rdevminor), |
113 | | DLSYM_ARG(archive_entry_set_size), |
114 | | DLSYM_ARG(archive_entry_set_symlink), |
115 | | DLSYM_ARG(archive_entry_set_uid), |
116 | | DLSYM_ARG(archive_entry_sparse_add_entry), |
117 | | DLSYM_ARG(archive_entry_symlink), |
118 | | DLSYM_ARG(archive_entry_uid), |
119 | | DLSYM_ARG(archive_entry_xattr_add_entry), |
120 | | DLSYM_ARG(archive_entry_xattr_next), |
121 | | DLSYM_ARG(archive_entry_xattr_reset), |
122 | | DLSYM_ARG(archive_error_string), |
123 | | DLSYM_ARG(archive_read_data_into_fd), |
124 | | DLSYM_ARG(archive_read_free), |
125 | | DLSYM_ARG(archive_read_new), |
126 | | DLSYM_ARG(archive_read_next_header), |
127 | | DLSYM_ARG(archive_read_open_fd), |
128 | | DLSYM_ARG(archive_read_support_format_cpio), |
129 | | DLSYM_ARG(archive_read_support_format_tar), |
130 | | DLSYM_ARG(archive_write_close), |
131 | | DLSYM_ARG(archive_write_data), |
132 | | DLSYM_ARG(archive_write_free), |
133 | | DLSYM_ARG(archive_write_header), |
134 | | DLSYM_ARG(archive_write_new), |
135 | | DLSYM_ARG(archive_write_open_FILE), |
136 | | DLSYM_ARG(archive_write_open_fd), |
137 | | DLSYM_ARG(archive_write_set_format_filter_by_ext), |
138 | | DLSYM_ARG(archive_write_set_format_pax)); |
139 | | if (r <= 0) |
140 | | return r; |
141 | | |
142 | | /* Optional symbols: archive_entry_gid_is_set and archive_entry_uid_is_set exist only in libarchive |
143 | | * 3.7.3+, archive_entry_hardlink_is_set exists only in 3.7.5+. If missing, sym_X keeps its |
144 | | * fallback-function initializer (see above). */ |
145 | | DLSYM_OPTIONAL(libarchive_dl, archive_entry_gid_is_set); |
146 | | DLSYM_OPTIONAL(libarchive_dl, archive_entry_uid_is_set); |
147 | | DLSYM_OPTIONAL(libarchive_dl, archive_entry_hardlink_is_set); |
148 | | |
149 | | return 1; |
150 | | #else |
151 | | return log_full_errno(log_level, SYNTHETIC_ERRNO(EOPNOTSUPP), |
152 | 0 | "libarchive support is not compiled in."); |
153 | 0 | #endif |
154 | 0 | } |
155 | | |
156 | | #if HAVE_LIBARCHIVE |
157 | | /* libarchive uses its own file type macros. They happen to be defined the same way as the Linux ones, and |
158 | | * we'd like to rely on it. Let's verify this first though. */ |
159 | | assert_cc(S_IFDIR == AE_IFDIR); |
160 | | assert_cc(S_IFREG == AE_IFREG); |
161 | | assert_cc(S_IFLNK == AE_IFLNK); |
162 | | assert_cc(S_IFBLK == AE_IFBLK); |
163 | | assert_cc(S_IFCHR == AE_IFCHR); |
164 | | assert_cc(S_IFIFO == AE_IFIFO); |
165 | | assert_cc(S_IFSOCK == AE_IFSOCK); |
166 | | |
167 | | #endif |