libarchive-static 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (157) hide show
  1. data/ext/Makefile +6 -0
  2. data/ext/extconf.rb +61 -0
  3. data/ext/libarchive-0.1.1/COPYING.libarchive +60 -0
  4. data/ext/libarchive-0.1.1/LICENSE.libbzip2 +42 -0
  5. data/ext/libarchive-0.1.1/README.txt +143 -0
  6. data/ext/libarchive-0.1.1/ext/Makefile.in +0 -0
  7. data/ext/libarchive-0.1.1/ext/archive_read_support_compression.c +31 -0
  8. data/ext/libarchive-0.1.1/ext/archive_read_support_compression.h +6 -0
  9. data/ext/libarchive-0.1.1/ext/archive_read_support_format.c +32 -0
  10. data/ext/libarchive-0.1.1/ext/archive_read_support_format.h +6 -0
  11. data/ext/libarchive-0.1.1/ext/archive_write_open_rb_str.c +29 -0
  12. data/ext/libarchive-0.1.1/ext/archive_write_open_rb_str.h +6 -0
  13. data/ext/libarchive-0.1.1/ext/archive_write_set_compression.c +32 -0
  14. data/ext/libarchive-0.1.1/ext/archive_write_set_compression.h +6 -0
  15. data/ext/libarchive-0.1.1/ext/config.h.in +22 -0
  16. data/ext/libarchive-0.1.1/ext/configure +3904 -0
  17. data/ext/libarchive-0.1.1/ext/configure.in +11 -0
  18. data/ext/libarchive-0.1.1/ext/depend +19 -0
  19. data/ext/libarchive-0.1.1/ext/extconf.rb +6 -0
  20. data/ext/libarchive-0.1.1/ext/install-sh +250 -0
  21. data/ext/libarchive-0.1.1/ext/libarchive.c +89 -0
  22. data/ext/libarchive-0.1.1/ext/libarchive_archive.c +84 -0
  23. data/ext/libarchive-0.1.1/ext/libarchive_entry.c +1015 -0
  24. data/ext/libarchive-0.1.1/ext/libarchive_internal.h +155 -0
  25. data/ext/libarchive-0.1.1/ext/libarchive_reader.c +328 -0
  26. data/ext/libarchive-0.1.1/ext/libarchive_win32.h +52 -0
  27. data/ext/libarchive-0.1.1/ext/libarchive_writer.c +246 -0
  28. data/ext/libarchive-0.1.1/libarchive.c +1762 -0
  29. data/ext/libarchive-2.8.4/Makefile.in +7076 -0
  30. data/ext/libarchive-2.8.4/build/autoconf/check_stdcall_func.m4 +51 -0
  31. data/ext/libarchive-2.8.4/build/autoconf/compile +143 -0
  32. data/ext/libarchive-2.8.4/build/autoconf/config.guess +1502 -0
  33. data/ext/libarchive-2.8.4/build/autoconf/config.sub +1708 -0
  34. data/ext/libarchive-2.8.4/build/autoconf/depcomp +630 -0
  35. data/ext/libarchive-2.8.4/build/autoconf/install-sh +291 -0
  36. data/ext/libarchive-2.8.4/build/autoconf/la_uid_t.m4 +20 -0
  37. data/ext/libarchive-2.8.4/build/autoconf/ltmain.sh +8406 -0
  38. data/ext/libarchive-2.8.4/build/autoconf/missing +376 -0
  39. data/ext/libarchive-2.8.4/build/pkgconfig/libarchive.pc.in +10 -0
  40. data/ext/libarchive-2.8.4/config.h.in +772 -0
  41. data/ext/libarchive-2.8.4/configure +17916 -0
  42. data/ext/libarchive-2.8.4/libarchive/archive.h +741 -0
  43. data/ext/libarchive-2.8.4/libarchive/archive_check_magic.c +134 -0
  44. data/ext/libarchive-2.8.4/libarchive/archive_crc32.h +66 -0
  45. data/ext/libarchive-2.8.4/libarchive/archive_endian.h +162 -0
  46. data/ext/libarchive-2.8.4/libarchive/archive_entry.c +2202 -0
  47. data/ext/libarchive-2.8.4/libarchive/archive_entry.h +524 -0
  48. data/ext/libarchive-2.8.4/libarchive/archive_entry_copy_bhfi.c +74 -0
  49. data/ext/libarchive-2.8.4/libarchive/archive_entry_copy_stat.c +77 -0
  50. data/ext/libarchive-2.8.4/libarchive/archive_entry_link_resolver.c +405 -0
  51. data/ext/libarchive-2.8.4/libarchive/archive_entry_private.h +184 -0
  52. data/ext/libarchive-2.8.4/libarchive/archive_entry_stat.c +118 -0
  53. data/ext/libarchive-2.8.4/libarchive/archive_entry_strmode.c +87 -0
  54. data/ext/libarchive-2.8.4/libarchive/archive_entry_xattr.c +158 -0
  55. data/ext/libarchive-2.8.4/libarchive/archive_hash.h +281 -0
  56. data/ext/libarchive-2.8.4/libarchive/archive_platform.h +165 -0
  57. data/ext/libarchive-2.8.4/libarchive/archive_private.h +124 -0
  58. data/ext/libarchive-2.8.4/libarchive/archive_read.c +1249 -0
  59. data/ext/libarchive-2.8.4/libarchive/archive_read_data_into_fd.c +93 -0
  60. data/ext/libarchive-2.8.4/libarchive/archive_read_disk.c +198 -0
  61. data/ext/libarchive-2.8.4/libarchive/archive_read_disk_entry_from_file.c +570 -0
  62. data/ext/libarchive-2.8.4/libarchive/archive_read_disk_private.h +62 -0
  63. data/ext/libarchive-2.8.4/libarchive/archive_read_disk_set_standard_lookup.c +303 -0
  64. data/ext/libarchive-2.8.4/libarchive/archive_read_extract.c +182 -0
  65. data/ext/libarchive-2.8.4/libarchive/archive_read_open_fd.c +190 -0
  66. data/ext/libarchive-2.8.4/libarchive/archive_read_open_file.c +165 -0
  67. data/ext/libarchive-2.8.4/libarchive/archive_read_open_filename.c +272 -0
  68. data/ext/libarchive-2.8.4/libarchive/archive_read_open_memory.c +156 -0
  69. data/ext/libarchive-2.8.4/libarchive/archive_read_private.h +199 -0
  70. data/ext/libarchive-2.8.4/libarchive/archive_read_support_compression_all.c +60 -0
  71. data/ext/libarchive-2.8.4/libarchive/archive_read_support_compression_bzip2.c +353 -0
  72. data/ext/libarchive-2.8.4/libarchive/archive_read_support_compression_compress.c +444 -0
  73. data/ext/libarchive-2.8.4/libarchive/archive_read_support_compression_gzip.c +465 -0
  74. data/ext/libarchive-2.8.4/libarchive/archive_read_support_compression_none.c +40 -0
  75. data/ext/libarchive-2.8.4/libarchive/archive_read_support_compression_program.c +459 -0
  76. data/ext/libarchive-2.8.4/libarchive/archive_read_support_compression_rpm.c +287 -0
  77. data/ext/libarchive-2.8.4/libarchive/archive_read_support_compression_uu.c +627 -0
  78. data/ext/libarchive-2.8.4/libarchive/archive_read_support_compression_xz.c +708 -0
  79. data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_all.c +43 -0
  80. data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_ar.c +584 -0
  81. data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_cpio.c +777 -0
  82. data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_empty.c +93 -0
  83. data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_iso9660.c +2830 -0
  84. data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_mtree.c +1304 -0
  85. data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_raw.c +185 -0
  86. data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_tar.c +2418 -0
  87. data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_xar.c +3151 -0
  88. data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_zip.c +903 -0
  89. data/ext/libarchive-2.8.4/libarchive/archive_string.c +453 -0
  90. data/ext/libarchive-2.8.4/libarchive/archive_string.h +148 -0
  91. data/ext/libarchive-2.8.4/libarchive/archive_string_sprintf.c +164 -0
  92. data/ext/libarchive-2.8.4/libarchive/archive_util.c +391 -0
  93. data/ext/libarchive-2.8.4/libarchive/archive_virtual.c +94 -0
  94. data/ext/libarchive-2.8.4/libarchive/archive_windows.c +1236 -0
  95. data/ext/libarchive-2.8.4/libarchive/archive_windows.h +347 -0
  96. data/ext/libarchive-2.8.4/libarchive/archive_write.c +466 -0
  97. data/ext/libarchive-2.8.4/libarchive/archive_write_disk.c +2628 -0
  98. data/ext/libarchive-2.8.4/libarchive/archive_write_disk_private.h +38 -0
  99. data/ext/libarchive-2.8.4/libarchive/archive_write_disk_set_standard_lookup.c +262 -0
  100. data/ext/libarchive-2.8.4/libarchive/archive_write_open_fd.c +141 -0
  101. data/ext/libarchive-2.8.4/libarchive/archive_write_open_file.c +105 -0
  102. data/ext/libarchive-2.8.4/libarchive/archive_write_open_filename.c +162 -0
  103. data/ext/libarchive-2.8.4/libarchive/archive_write_open_memory.c +126 -0
  104. data/ext/libarchive-2.8.4/libarchive/archive_write_private.h +122 -0
  105. data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_bzip2.c +408 -0
  106. data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_compress.c +492 -0
  107. data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_gzip.c +477 -0
  108. data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_none.c +257 -0
  109. data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_program.c +347 -0
  110. data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_xz.c +438 -0
  111. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format.c +72 -0
  112. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_ar.c +550 -0
  113. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_by_name.c +76 -0
  114. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_cpio.c +344 -0
  115. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_cpio_newc.c +295 -0
  116. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_mtree.c +1050 -0
  117. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_pax.c +1386 -0
  118. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_shar.c +626 -0
  119. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_ustar.c +587 -0
  120. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_zip.c +667 -0
  121. data/ext/libarchive-2.8.4/libarchive/config_freebsd.h +154 -0
  122. data/ext/libarchive-2.8.4/libarchive/filter_fork.c +161 -0
  123. data/ext/libarchive-2.8.4/libarchive/filter_fork.h +41 -0
  124. data/ext/libarchive-2.8.4/libarchive/filter_fork_windows.c +113 -0
  125. data/ext/libarchive-static-makefile +80 -0
  126. data/ext/libarchive-static-wrapper-makefile +22 -0
  127. data/ext/zlib-1.2.5/Makefile.in +257 -0
  128. data/ext/zlib-1.2.5/adler32.c +169 -0
  129. data/ext/zlib-1.2.5/compress.c +80 -0
  130. data/ext/zlib-1.2.5/configure +596 -0
  131. data/ext/zlib-1.2.5/crc32.c +442 -0
  132. data/ext/zlib-1.2.5/crc32.h +441 -0
  133. data/ext/zlib-1.2.5/deflate.c +1834 -0
  134. data/ext/zlib-1.2.5/deflate.h +342 -0
  135. data/ext/zlib-1.2.5/example.c +565 -0
  136. data/ext/zlib-1.2.5/gzclose.c +25 -0
  137. data/ext/zlib-1.2.5/gzguts.h +132 -0
  138. data/ext/zlib-1.2.5/gzlib.c +537 -0
  139. data/ext/zlib-1.2.5/gzread.c +653 -0
  140. data/ext/zlib-1.2.5/gzwrite.c +531 -0
  141. data/ext/zlib-1.2.5/infback.c +632 -0
  142. data/ext/zlib-1.2.5/inffast.c +340 -0
  143. data/ext/zlib-1.2.5/inffast.h +11 -0
  144. data/ext/zlib-1.2.5/inffixed.h +94 -0
  145. data/ext/zlib-1.2.5/inflate.c +1480 -0
  146. data/ext/zlib-1.2.5/inflate.h +122 -0
  147. data/ext/zlib-1.2.5/inftrees.c +330 -0
  148. data/ext/zlib-1.2.5/inftrees.h +62 -0
  149. data/ext/zlib-1.2.5/minigzip.c +440 -0
  150. data/ext/zlib-1.2.5/trees.c +1244 -0
  151. data/ext/zlib-1.2.5/trees.h +128 -0
  152. data/ext/zlib-1.2.5/uncompr.c +59 -0
  153. data/ext/zlib-1.2.5/zconf.h +428 -0
  154. data/ext/zlib-1.2.5/zlib.h +1613 -0
  155. data/ext/zlib-1.2.5/zutil.c +318 -0
  156. data/ext/zlib-1.2.5/zutil.h +274 -0
  157. metadata +211 -0
@@ -0,0 +1,1050 @@
1
+ /*-
2
+ * Copyright (c) 2009 Michihiro NAKAJIMA
3
+ * Copyright (c) 2008 Joerg Sonnenberger
4
+ * All rights reserved.
5
+ *
6
+ * Redistribution and use in source and binary forms, with or without
7
+ * modification, are permitted provided that the following conditions
8
+ * are met:
9
+ * 1. Redistributions of source code must retain the above copyright
10
+ * notice, this list of conditions and the following disclaimer.
11
+ * 2. Redistributions in binary form must reproduce the above copyright
12
+ * notice, this list of conditions and the following disclaimer in the
13
+ * documentation and/or other materials provided with the distribution.
14
+ *
15
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
16
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
19
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
+ */
26
+
27
+ #include "archive_platform.h"
28
+ __FBSDID("$FreeBSD: head/lib/libarchive/archive_write_set_format_mtree.c 201171 2009-12-29 06:39:07Z kientzle $");
29
+
30
+ #ifdef HAVE_SYS_TYPES_H
31
+ #include <sys/types.h>
32
+ #endif
33
+ #include <errno.h>
34
+ #include <stdlib.h>
35
+ #include <string.h>
36
+
37
+ #include "archive.h"
38
+ #include "archive_entry.h"
39
+ #include "archive_private.h"
40
+ #include "archive_write_private.h"
41
+
42
+ #include "archive_hash.h"
43
+
44
+ #define INDENTNAMELEN 15
45
+ #define MAXLINELEN 80
46
+
47
+ struct mtree_writer {
48
+ struct archive_entry *entry;
49
+ struct archive_string ebuf;
50
+ struct archive_string buf;
51
+ int first;
52
+ uint64_t entry_bytes_remaining;
53
+ struct {
54
+ int output;
55
+ int processed;
56
+ struct archive_string parent;
57
+ mode_t type;
58
+ int keys;
59
+ uid_t uid;
60
+ gid_t gid;
61
+ mode_t mode;
62
+ unsigned long fflags_set;
63
+ unsigned long fflags_clear;
64
+ } set;
65
+ /* chekc sum */
66
+ int compute_sum;
67
+ uint32_t crc;
68
+ uint64_t crc_len;
69
+ #ifdef ARCHIVE_HAS_MD5
70
+ archive_md5_ctx md5ctx;
71
+ #endif
72
+ #ifdef ARCHIVE_HAS_RMD160
73
+ archive_rmd160_ctx rmd160ctx;
74
+ #endif
75
+ #ifdef ARCHIVE_HAS_SHA1
76
+ archive_sha1_ctx sha1ctx;
77
+ #endif
78
+ #ifdef ARCHIVE_HAS_SHA256
79
+ archive_sha256_ctx sha256ctx;
80
+ #endif
81
+ #ifdef ARCHIVE_HAS_SHA384
82
+ archive_sha384_ctx sha384ctx;
83
+ #endif
84
+ #ifdef ARCHIVE_HAS_SHA512
85
+ archive_sha512_ctx sha512ctx;
86
+ #endif
87
+ /* Keyword options */
88
+ int keys;
89
+ #define F_CKSUM 0x00000001 /* check sum */
90
+ #define F_DEV 0x00000002 /* device type */
91
+ #define F_DONE 0x00000004 /* directory done */
92
+ #define F_FLAGS 0x00000008 /* file flags */
93
+ #define F_GID 0x00000010 /* gid */
94
+ #define F_GNAME 0x00000020 /* group name */
95
+ #define F_IGN 0x00000040 /* ignore */
96
+ #define F_MAGIC 0x00000080 /* name has magic chars */
97
+ #define F_MD5 0x00000100 /* MD5 digest */
98
+ #define F_MODE 0x00000200 /* mode */
99
+ #define F_NLINK 0x00000400 /* number of links */
100
+ #define F_NOCHANGE 0x00000800 /* If owner/mode "wrong", do
101
+ * not change */
102
+ #define F_OPT 0x00001000 /* existence optional */
103
+ #define F_RMD160 0x00002000 /* RIPEMD160 digest */
104
+ #define F_SHA1 0x00004000 /* SHA-1 digest */
105
+ #define F_SIZE 0x00008000 /* size */
106
+ #define F_SLINK 0x00010000 /* symbolic link */
107
+ #define F_TAGS 0x00020000 /* tags */
108
+ #define F_TIME 0x00040000 /* modification time */
109
+ #define F_TYPE 0x00080000 /* file type */
110
+ #define F_UID 0x00100000 /* uid */
111
+ #define F_UNAME 0x00200000 /* user name */
112
+ #define F_VISIT 0x00400000 /* file visited */
113
+ #define F_SHA256 0x00800000 /* SHA-256 digest */
114
+ #define F_SHA384 0x01000000 /* SHA-384 digest */
115
+ #define F_SHA512 0x02000000 /* SHA-512 digest */
116
+
117
+ /* Options */
118
+ int dironly; /* if the dironly is 1, ignore everything except
119
+ * directory type files. like mtree(8) -d option.
120
+ */
121
+ int indent; /* if the indent is 1, indent writing data. */
122
+ };
123
+
124
+ #define DEFAULT_KEYS (F_DEV | F_FLAGS | F_GID | F_GNAME | F_SLINK | F_MODE\
125
+ | F_NLINK | F_SIZE | F_TIME | F_TYPE | F_UID\
126
+ | F_UNAME)
127
+
128
+ #define COMPUTE_CRC(var, ch) (var) = (var) << 8 ^ crctab[(var) >> 24 ^ (ch)]
129
+ static const uint32_t crctab[] = {
130
+ 0x0,
131
+ 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b,
132
+ 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6,
133
+ 0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd,
134
+ 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac,
135
+ 0x5bd4b01b, 0x569796c2, 0x52568b75, 0x6a1936c8, 0x6ed82b7f,
136
+ 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a,
137
+ 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039,
138
+ 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58,
139
+ 0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033,
140
+ 0xa4ad16ea, 0xa06c0b5d, 0xd4326d90, 0xd0f37027, 0xddb056fe,
141
+ 0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95,
142
+ 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4,
143
+ 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0,
144
+ 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5,
145
+ 0x2ac12072, 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16,
146
+ 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, 0x7897ab07,
147
+ 0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c,
148
+ 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1,
149
+ 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba,
150
+ 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b,
151
+ 0xbb60adfc, 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698,
152
+ 0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d,
153
+ 0x94ea7b2a, 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e,
154
+ 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, 0xc6bcf05f,
155
+ 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34,
156
+ 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80,
157
+ 0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb,
158
+ 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a,
159
+ 0x58c1663d, 0x558240e4, 0x51435d53, 0x251d3b9e, 0x21dc2629,
160
+ 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c,
161
+ 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff,
162
+ 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e,
163
+ 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65,
164
+ 0xeba91bbc, 0xef68060b, 0xd727bbb6, 0xd3e6a601, 0xdea580d8,
165
+ 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3,
166
+ 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2,
167
+ 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71,
168
+ 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74,
169
+ 0x857130c3, 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640,
170
+ 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, 0x7b827d21,
171
+ 0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a,
172
+ 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, 0x18197087,
173
+ 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec,
174
+ 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d,
175
+ 0x2056cd3a, 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce,
176
+ 0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb,
177
+ 0xdbee767c, 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18,
178
+ 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 0x89b8fd09,
179
+ 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662,
180
+ 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf,
181
+ 0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4
182
+ };
183
+
184
+ static int
185
+ mtree_safe_char(char c)
186
+ {
187
+ if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
188
+ return 1;
189
+ if (c >= '0' && c <= '9')
190
+ return 1;
191
+ if (c == 35 || c == 61 || c == 92)
192
+ return 0; /* #, = and \ are always quoted */
193
+
194
+ if (c >= 33 && c <= 47) /* !"$%&'()*+,-./ */
195
+ return 1;
196
+ if (c >= 58 && c <= 64) /* :;<>?@ */
197
+ return 1;
198
+ if (c >= 91 && c <= 96) /* []^_` */
199
+ return 1;
200
+ if (c >= 123 && c <= 126) /* {|}~ */
201
+ return 1;
202
+ return 0;
203
+ }
204
+
205
+ static void
206
+ mtree_quote(struct archive_string *s, const char *str)
207
+ {
208
+ const char *start;
209
+ char buf[4];
210
+ unsigned char c;
211
+
212
+ for (start = str; *str != '\0'; ++str) {
213
+ if (mtree_safe_char(*str))
214
+ continue;
215
+ if (start != str)
216
+ archive_strncat(s, start, str - start);
217
+ c = (unsigned char)*str;
218
+ buf[0] = '\\';
219
+ buf[1] = (c / 64) + '0';
220
+ buf[2] = (c / 8 % 8) + '0';
221
+ buf[3] = (c % 8) + '0';
222
+ archive_strncat(s, buf, 4);
223
+ start = str + 1;
224
+ }
225
+
226
+ if (start != str)
227
+ archive_strncat(s, start, str - start);
228
+ }
229
+
230
+ static void
231
+ mtree_indent(struct mtree_writer *mtree)
232
+ {
233
+ int i, fn;
234
+ const char *r, *s, *x;
235
+
236
+ fn = 1;
237
+ s = r = mtree->ebuf.s;
238
+ x = NULL;
239
+ while (*r == ' ')
240
+ r++;
241
+ while ((r = strchr(r, ' ')) != NULL) {
242
+ if (fn) {
243
+ fn = 0;
244
+ archive_strncat(&mtree->buf, s, r - s);
245
+ if (r -s > INDENTNAMELEN) {
246
+ archive_strncat(&mtree->buf, " \\\n", 3);
247
+ for (i = 0; i < (INDENTNAMELEN + 1); i++)
248
+ archive_strappend_char(&mtree->buf, ' ');
249
+ } else {
250
+ for (i = r -s; i < (INDENTNAMELEN + 1); i++)
251
+ archive_strappend_char(&mtree->buf, ' ');
252
+ }
253
+ s = ++r;
254
+ x = NULL;
255
+ continue;
256
+ }
257
+ if (r - s <= MAXLINELEN - 3 - INDENTNAMELEN)
258
+ x = r++;
259
+ else {
260
+ if (x == NULL)
261
+ x = r;
262
+ archive_strncat(&mtree->buf, s, x - s);
263
+ archive_strncat(&mtree->buf, " \\\n", 3);
264
+ for (i = 0; i < (INDENTNAMELEN + 1); i++)
265
+ archive_strappend_char(&mtree->buf, ' ');
266
+ s = r = ++x;
267
+ x = NULL;
268
+ }
269
+ }
270
+ if (x != NULL && strlen(s) > MAXLINELEN - 3 - INDENTNAMELEN) {
271
+ /* Last keyword is longer. */
272
+ archive_strncat(&mtree->buf, s, x - s);
273
+ archive_strncat(&mtree->buf, " \\\n", 3);
274
+ for (i = 0; i < (INDENTNAMELEN + 1); i++)
275
+ archive_strappend_char(&mtree->buf, ' ');
276
+ s = ++x;
277
+ }
278
+ archive_strcat(&mtree->buf, s);
279
+ archive_string_empty(&mtree->ebuf);
280
+ }
281
+
282
+ #if !defined(_WIN32) || defined(__CYGWIN__)
283
+ static size_t
284
+ dir_len(struct archive_entry *entry)
285
+ {
286
+ const char *path, *r;
287
+
288
+ path = archive_entry_pathname(entry);
289
+ r = strrchr(path, '/');
290
+ if (r == NULL)
291
+ return (0);
292
+ /* Include a separator size */
293
+ return (r - path + 1);
294
+ }
295
+
296
+ #else /* _WIN32 && !__CYGWIN__ */
297
+ /*
298
+ * Note: We should use wide-character for findng '\' character,
299
+ * a directory separator on Windows, because some character-set have
300
+ * been using the '\' character for a part of its multibyte character
301
+ * code.
302
+ */
303
+ static size_t
304
+ dir_len(struct archive_entry *entry)
305
+ {
306
+ wchar_t wc;
307
+ const char *path;
308
+ const char *p, *rp;
309
+ size_t al, l, size;
310
+
311
+ path = archive_entry_pathname(entry);
312
+ al = l = -1;
313
+ for (p = path; *p != '\0'; ++p) {
314
+ if (*p == '\\')
315
+ al = l = p - path;
316
+ else if (*p == '/')
317
+ al = p - path;
318
+ }
319
+ if (l == -1)
320
+ goto alen;
321
+ size = p - path;
322
+ rp = p = path;
323
+ while (*p != '\0') {
324
+ l = mbtowc(&wc, p, size);
325
+ if (l == -1)
326
+ goto alen;
327
+ if (l == 1 && (wc == L'/' || wc == L'\\'))
328
+ rp = p;
329
+ p += l;
330
+ size -= l;
331
+ }
332
+ return (rp - path + 1);
333
+ alen:
334
+ if (al == -1)
335
+ return (0);
336
+ return (al + 1);
337
+ }
338
+ #endif /* _WIN32 && !__CYGWIN__ */
339
+
340
+ static int
341
+ parent_dir_changed(struct archive_string *dir, struct archive_entry *entry)
342
+ {
343
+ const char *path;
344
+ size_t l;
345
+
346
+ l = dir_len(entry);
347
+ path = archive_entry_pathname(entry);
348
+ if (archive_strlen(dir) > 0) {
349
+ if (l == 0) {
350
+ archive_string_empty(dir);
351
+ return (1);
352
+ }
353
+ if (strncmp(dir->s, path, l) == 0)
354
+ return (0); /* The parent directory is the same. */
355
+ } else if (l == 0)
356
+ return (0); /* The parent directory is the same. */
357
+ archive_strncpy(dir, path, l);
358
+ return (1);
359
+ }
360
+
361
+ /*
362
+ * Write /set keyword. It means set global datas.
363
+ * [directory-only mode]
364
+ * - It is only once to write /set keyword. It is using values of the
365
+ * first entry.
366
+ * [normal mode]
367
+ * - Write /set keyword. It is using values of the first entry whose
368
+ * filetype is a regular file.
369
+ * - When a parent directory of the entry whose filetype is the regular
370
+ * file is changed, check the global datas and write it again if its
371
+ * values are different from the entry's.
372
+ */
373
+ static void
374
+ set_global(struct mtree_writer *mtree, struct archive_entry *entry)
375
+ {
376
+ struct archive_string setstr;
377
+ struct archive_string unsetstr;
378
+ const char *name;
379
+ int keys, oldkeys, effkeys;
380
+ mode_t set_type = 0;
381
+
382
+ switch (archive_entry_filetype(entry)) {
383
+ case AE_IFLNK: case AE_IFSOCK: case AE_IFCHR:
384
+ case AE_IFBLK: case AE_IFIFO:
385
+ break;
386
+ case AE_IFDIR:
387
+ if (mtree->dironly)
388
+ set_type = AE_IFDIR;
389
+ break;
390
+ case AE_IFREG:
391
+ default: /* Handle unknown file types as regular files. */
392
+ if (!mtree->dironly)
393
+ set_type = AE_IFREG;
394
+ break;
395
+ }
396
+ if (set_type == 0)
397
+ return;
398
+ if (mtree->set.processed &&
399
+ !parent_dir_changed(&mtree->set.parent, entry))
400
+ return;
401
+ /* At first, save a parent directory of the entry for following
402
+ * entries. */
403
+ if (!mtree->set.processed && set_type == AE_IFREG)
404
+ parent_dir_changed(&mtree->set.parent, entry);
405
+
406
+ archive_string_init(&setstr);
407
+ archive_string_init(&unsetstr);
408
+ keys = mtree->keys & (F_FLAGS | F_GID | F_GNAME | F_NLINK | F_MODE
409
+ | F_TYPE | F_UID | F_UNAME);
410
+ oldkeys = mtree->set.keys;
411
+ effkeys = keys;
412
+ if (mtree->set.processed) {
413
+ /*
414
+ * Check the global datas for whether it needs updating.
415
+ */
416
+ effkeys &= ~F_TYPE;
417
+ if ((oldkeys & (F_UNAME | F_UID)) != 0 &&
418
+ mtree->set.uid == archive_entry_uid(entry))
419
+ effkeys &= ~(F_UNAME | F_UID);
420
+ if ((oldkeys & (F_GNAME | F_GID)) != 0 &&
421
+ mtree->set.gid == archive_entry_gid(entry))
422
+ effkeys &= ~(F_GNAME | F_GID);
423
+ if ((oldkeys & F_MODE) != 0 &&
424
+ mtree->set.mode == (archive_entry_mode(entry) & 07777))
425
+ effkeys &= ~F_MODE;
426
+ if ((oldkeys & F_FLAGS) != 0) {
427
+ unsigned long fflags_set;
428
+ unsigned long fflags_clear;
429
+
430
+ archive_entry_fflags(entry, &fflags_set, &fflags_clear);
431
+ if (fflags_set == mtree->set.fflags_set &&
432
+ fflags_clear == mtree->set.fflags_clear)
433
+ effkeys &= ~F_FLAGS;
434
+ }
435
+ }
436
+ if ((keys & effkeys & F_TYPE) != 0) {
437
+ mtree->set.type = set_type;
438
+ if (set_type == AE_IFDIR)
439
+ archive_strcat(&setstr, " type=dir");
440
+ else
441
+ archive_strcat(&setstr, " type=file");
442
+ }
443
+ if ((keys & effkeys & F_UNAME) != 0) {
444
+ if ((name = archive_entry_uname(entry)) != NULL) {
445
+ archive_strcat(&setstr, " uname=");
446
+ mtree_quote(&setstr, name);
447
+ } else if ((oldkeys & F_UNAME) != 0)
448
+ archive_strcat(&unsetstr, " uname");
449
+ else
450
+ keys &= ~F_UNAME;
451
+ }
452
+ if ((keys & effkeys & F_UID) != 0) {
453
+ mtree->set.uid = archive_entry_uid(entry);
454
+ archive_string_sprintf(&setstr, " uid=%jd",
455
+ (intmax_t)mtree->set.uid);
456
+ }
457
+ if ((keys & effkeys & F_GNAME) != 0) {
458
+ if ((name = archive_entry_gname(entry)) != NULL) {
459
+ archive_strcat(&setstr, " gname=");
460
+ mtree_quote(&setstr, name);
461
+ } else if ((oldkeys & F_GNAME) != 0)
462
+ archive_strcat(&unsetstr, " gname");
463
+ else
464
+ keys &= ~F_GNAME;
465
+ }
466
+ if ((keys & effkeys & F_GID) != 0) {
467
+ mtree->set.gid = archive_entry_gid(entry);
468
+ archive_string_sprintf(&setstr, " gid=%jd",
469
+ (intmax_t)mtree->set.gid);
470
+ }
471
+ if ((keys & effkeys & F_MODE) != 0) {
472
+ mtree->set.mode = archive_entry_mode(entry) & 07777;
473
+ archive_string_sprintf(&setstr, " mode=%o", mtree->set.mode);
474
+ }
475
+ if ((keys & effkeys & F_FLAGS) != 0) {
476
+ if ((name = archive_entry_fflags_text(entry)) != NULL) {
477
+ archive_strcat(&setstr, " flags=");
478
+ mtree_quote(&setstr, name);
479
+ archive_entry_fflags(entry, &mtree->set.fflags_set,
480
+ &mtree->set.fflags_clear);
481
+ } else if ((oldkeys & F_FLAGS) != 0)
482
+ archive_strcat(&unsetstr, " flags");
483
+ else
484
+ keys &= ~F_FLAGS;
485
+ }
486
+ if (unsetstr.length > 0)
487
+ archive_string_sprintf(&mtree->buf, "/unset%s\n", unsetstr.s);
488
+ archive_string_free(&unsetstr);
489
+ if (setstr.length > 0)
490
+ archive_string_sprintf(&mtree->buf, "/set%s\n", setstr.s);
491
+ archive_string_free(&setstr);
492
+ mtree->set.keys = keys;
493
+ mtree->set.processed = 1;
494
+ /* On directory-only mode, it is only once to write /set keyword. */
495
+ if (mtree->dironly)
496
+ mtree->set.output = 0;
497
+ }
498
+
499
+ static int
500
+ get_keys(struct mtree_writer *mtree, struct archive_entry *entry)
501
+ {
502
+ int keys;
503
+
504
+ keys = mtree->keys;
505
+ if (mtree->set.keys == 0)
506
+ return (keys);
507
+ if ((mtree->set.keys & (F_GNAME | F_GID)) != 0 &&
508
+ mtree->set.gid == archive_entry_gid(entry))
509
+ keys &= ~(F_GNAME | F_GID);
510
+ if ((mtree->set.keys & (F_UNAME | F_UID)) != 0 &&
511
+ mtree->set.uid == archive_entry_uid(entry))
512
+ keys &= ~(F_UNAME | F_UID);
513
+ if (mtree->set.keys & F_FLAGS) {
514
+ unsigned long set, clear;
515
+
516
+ archive_entry_fflags(entry, &set, &clear);
517
+ if (mtree->set.fflags_set == set &&
518
+ mtree->set.fflags_clear == clear)
519
+ keys &= ~F_FLAGS;
520
+ }
521
+ if ((mtree->set.keys & F_MODE) != 0 &&
522
+ mtree->set.mode == (archive_entry_mode(entry) & 07777))
523
+ keys &= ~F_MODE;
524
+
525
+ switch (archive_entry_filetype(entry)) {
526
+ case AE_IFLNK: case AE_IFSOCK: case AE_IFCHR:
527
+ case AE_IFBLK: case AE_IFIFO:
528
+ break;
529
+ case AE_IFDIR:
530
+ if ((mtree->set.keys & F_TYPE) != 0 &&
531
+ mtree->set.type == AE_IFDIR)
532
+ keys &= ~F_TYPE;
533
+ break;
534
+ case AE_IFREG:
535
+ default: /* Handle unknown file types as regular files. */
536
+ if ((mtree->set.keys & F_TYPE) != 0 &&
537
+ mtree->set.type == AE_IFREG)
538
+ keys &= ~F_TYPE;
539
+ break;
540
+ }
541
+
542
+ return (keys);
543
+ }
544
+
545
+ static int
546
+ archive_write_mtree_header(struct archive_write *a,
547
+ struct archive_entry *entry)
548
+ {
549
+ struct mtree_writer *mtree= a->format_data;
550
+ struct archive_string *str;
551
+ const char *path;
552
+
553
+ mtree->entry = archive_entry_clone(entry);
554
+ path = archive_entry_pathname(mtree->entry);
555
+
556
+ if (mtree->first) {
557
+ mtree->first = 0;
558
+ archive_strcat(&mtree->buf, "#mtree\n");
559
+ }
560
+ if (mtree->set.output)
561
+ set_global(mtree, entry);
562
+
563
+ archive_string_empty(&mtree->ebuf);
564
+ str = (mtree->indent)? &mtree->ebuf : &mtree->buf;
565
+ if (!mtree->dironly || archive_entry_filetype(entry) == AE_IFDIR)
566
+ mtree_quote(str, path);
567
+
568
+ mtree->entry_bytes_remaining = archive_entry_size(entry);
569
+ if ((mtree->keys & F_CKSUM) != 0 &&
570
+ archive_entry_filetype(entry) == AE_IFREG) {
571
+ mtree->compute_sum |= F_CKSUM;
572
+ mtree->crc = 0;
573
+ mtree->crc_len = 0;
574
+ } else
575
+ mtree->compute_sum &= ~F_CKSUM;
576
+ #ifdef ARCHIVE_HAS_MD5
577
+ if ((mtree->keys & F_MD5) != 0 &&
578
+ archive_entry_filetype(entry) == AE_IFREG) {
579
+ mtree->compute_sum |= F_MD5;
580
+ archive_md5_init(&mtree->md5ctx);
581
+ } else
582
+ mtree->compute_sum &= ~F_MD5;
583
+ #endif
584
+ #ifdef ARCHIVE_HAS_RMD160
585
+ if ((mtree->keys & F_RMD160) != 0 &&
586
+ archive_entry_filetype(entry) == AE_IFREG) {
587
+ mtree->compute_sum |= F_RMD160;
588
+ archive_rmd160_init(&mtree->rmd160ctx);
589
+ } else
590
+ mtree->compute_sum &= ~F_RMD160;
591
+ #endif
592
+ #ifdef ARCHIVE_HAS_SHA1
593
+ if ((mtree->keys & F_SHA1) != 0 &&
594
+ archive_entry_filetype(entry) == AE_IFREG) {
595
+ mtree->compute_sum |= F_SHA1;
596
+ archive_sha1_init(&mtree->sha1ctx);
597
+ } else
598
+ mtree->compute_sum &= ~F_SHA1;
599
+ #endif
600
+ #ifdef ARCHIVE_HAS_SHA256
601
+ if ((mtree->keys & F_SHA256) != 0 &&
602
+ archive_entry_filetype(entry) == AE_IFREG) {
603
+ mtree->compute_sum |= F_SHA256;
604
+ archive_sha256_init(&mtree->sha256ctx);
605
+ } else
606
+ mtree->compute_sum &= ~F_SHA256;
607
+ #endif
608
+ #ifdef ARCHIVE_HAS_SHA384
609
+ if ((mtree->keys & F_SHA384) != 0 &&
610
+ archive_entry_filetype(entry) == AE_IFREG) {
611
+ mtree->compute_sum |= F_SHA384;
612
+ archive_sha384_init(&mtree->sha384ctx);
613
+ } else
614
+ mtree->compute_sum &= ~F_SHA384;
615
+ #endif
616
+ #ifdef ARCHIVE_HAS_SHA512
617
+ if ((mtree->keys & F_SHA512) != 0 &&
618
+ archive_entry_filetype(entry) == AE_IFREG) {
619
+ mtree->compute_sum |= F_SHA512;
620
+ archive_sha512_init(&mtree->sha512ctx);
621
+ } else
622
+ mtree->compute_sum &= ~F_SHA512;
623
+ #endif
624
+
625
+ return (ARCHIVE_OK);
626
+ }
627
+
628
+ #if defined(ARCHIVE_HAS_MD5) || defined(ARCHIVE_HAS_RMD160) || \
629
+ defined(ARCHIVE_HAS_SHA1) || defined(ARCHIVE_HAS_SHA256) || \
630
+ defined(ARCHIVE_HAS_SHA384) || defined(ARCHIVE_HAS_SHA512)
631
+ static void
632
+ strappend_bin(struct archive_string *s, const unsigned char *bin, int n)
633
+ {
634
+ static const char hex[] = "0123456789abcdef";
635
+ int i;
636
+
637
+ for (i = 0; i < n; i++) {
638
+ archive_strappend_char(s, hex[bin[i] >> 4]);
639
+ archive_strappend_char(s, hex[bin[i] & 0x0f]);
640
+ }
641
+ }
642
+ #endif
643
+
644
+ static int
645
+ archive_write_mtree_finish_entry(struct archive_write *a)
646
+ {
647
+ struct mtree_writer *mtree = a->format_data;
648
+ struct archive_entry *entry;
649
+ struct archive_string *str;
650
+ const char *name;
651
+ int keys, ret;
652
+
653
+ entry = mtree->entry;
654
+ if (entry == NULL) {
655
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
656
+ "Finished entry without being open first.");
657
+ return (ARCHIVE_FATAL);
658
+ }
659
+ mtree->entry = NULL;
660
+
661
+ if (mtree->dironly && archive_entry_filetype(entry) != AE_IFDIR) {
662
+ archive_entry_free(entry);
663
+ return (ARCHIVE_OK);
664
+ }
665
+
666
+ str = (mtree->indent)? &mtree->ebuf : &mtree->buf;
667
+ keys = get_keys(mtree, entry);
668
+ if ((keys & F_NLINK) != 0 &&
669
+ archive_entry_nlink(entry) != 1 &&
670
+ archive_entry_filetype(entry) != AE_IFDIR)
671
+ archive_string_sprintf(str,
672
+ " nlink=%u", archive_entry_nlink(entry));
673
+
674
+ if ((keys & F_GNAME) != 0 &&
675
+ (name = archive_entry_gname(entry)) != NULL) {
676
+ archive_strcat(str, " gname=");
677
+ mtree_quote(str, name);
678
+ }
679
+ if ((keys & F_UNAME) != 0 &&
680
+ (name = archive_entry_uname(entry)) != NULL) {
681
+ archive_strcat(str, " uname=");
682
+ mtree_quote(str, name);
683
+ }
684
+ if ((keys & F_FLAGS) != 0 &&
685
+ (name = archive_entry_fflags_text(entry)) != NULL) {
686
+ archive_strcat(str, " flags=");
687
+ mtree_quote(str, name);
688
+ }
689
+ if ((keys & F_TIME) != 0)
690
+ archive_string_sprintf(str, " time=%jd.%jd",
691
+ (intmax_t)archive_entry_mtime(entry),
692
+ (intmax_t)archive_entry_mtime_nsec(entry));
693
+ if ((keys & F_MODE) != 0)
694
+ archive_string_sprintf(str, " mode=%o",
695
+ archive_entry_mode(entry) & 07777);
696
+ if ((keys & F_GID) != 0)
697
+ archive_string_sprintf(str, " gid=%jd",
698
+ (intmax_t)archive_entry_gid(entry));
699
+ if ((keys & F_UID) != 0)
700
+ archive_string_sprintf(str, " uid=%jd",
701
+ (intmax_t)archive_entry_uid(entry));
702
+
703
+ switch (archive_entry_filetype(entry)) {
704
+ case AE_IFLNK:
705
+ if ((keys & F_TYPE) != 0)
706
+ archive_strcat(str, " type=link");
707
+ if ((keys & F_SLINK) != 0) {
708
+ archive_strcat(str, " link=");
709
+ mtree_quote(str, archive_entry_symlink(entry));
710
+ }
711
+ break;
712
+ case AE_IFSOCK:
713
+ if ((keys & F_TYPE) != 0)
714
+ archive_strcat(str, " type=socket");
715
+ break;
716
+ case AE_IFCHR:
717
+ if ((keys & F_TYPE) != 0)
718
+ archive_strcat(str, " type=char");
719
+ if ((keys & F_DEV) != 0) {
720
+ archive_string_sprintf(str,
721
+ " device=native,%d,%d",
722
+ archive_entry_rdevmajor(entry),
723
+ archive_entry_rdevminor(entry));
724
+ }
725
+ break;
726
+ case AE_IFBLK:
727
+ if ((keys & F_TYPE) != 0)
728
+ archive_strcat(str, " type=block");
729
+ if ((keys & F_DEV) != 0) {
730
+ archive_string_sprintf(str,
731
+ " device=native,%d,%d",
732
+ archive_entry_rdevmajor(entry),
733
+ archive_entry_rdevminor(entry));
734
+ }
735
+ break;
736
+ case AE_IFDIR:
737
+ if ((keys & F_TYPE) != 0)
738
+ archive_strcat(str, " type=dir");
739
+ break;
740
+ case AE_IFIFO:
741
+ if ((keys & F_TYPE) != 0)
742
+ archive_strcat(str, " type=fifo");
743
+ break;
744
+ case AE_IFREG:
745
+ default: /* Handle unknown file types as regular files. */
746
+ if ((keys & F_TYPE) != 0)
747
+ archive_strcat(str, " type=file");
748
+ if ((keys & F_SIZE) != 0)
749
+ archive_string_sprintf(str, " size=%jd",
750
+ (intmax_t)archive_entry_size(entry));
751
+ break;
752
+ }
753
+
754
+ if (mtree->compute_sum & F_CKSUM) {
755
+ uint64_t len;
756
+ /* Include the length of the file. */
757
+ for (len = mtree->crc_len; len != 0; len >>= 8)
758
+ COMPUTE_CRC(mtree->crc, len & 0xff);
759
+ mtree->crc = ~mtree->crc;
760
+ archive_string_sprintf(str, " cksum=%ju",
761
+ (uintmax_t)mtree->crc);
762
+ }
763
+ #ifdef ARCHIVE_HAS_MD5
764
+ if (mtree->compute_sum & F_MD5) {
765
+ unsigned char buf[16];
766
+
767
+ archive_md5_final(&mtree->md5ctx, buf);
768
+ archive_strcat(str, " md5digest=");
769
+ strappend_bin(str, buf, sizeof(buf));
770
+ }
771
+ #endif
772
+ #ifdef ARCHIVE_HAS_RMD160
773
+ if (mtree->compute_sum & F_RMD160) {
774
+ unsigned char buf[20];
775
+
776
+ archive_rmd160_final(&mtree->rmd160ctx, buf);
777
+ archive_strcat(str, " rmd160digest=");
778
+ strappend_bin(str, buf, sizeof(buf));
779
+ }
780
+ #endif
781
+ #ifdef ARCHIVE_HAS_SHA1
782
+ if (mtree->compute_sum & F_SHA1) {
783
+ unsigned char buf[20];
784
+
785
+ archive_sha1_final(&mtree->sha1ctx, buf);
786
+ archive_strcat(str, " sha1digest=");
787
+ strappend_bin(str, buf, sizeof(buf));
788
+ }
789
+ #endif
790
+ #ifdef ARCHIVE_HAS_SHA256
791
+ if (mtree->compute_sum & F_SHA256) {
792
+ unsigned char buf[32];
793
+
794
+ archive_sha256_final(&mtree->sha256ctx, buf);
795
+ archive_strcat(str, " sha256digest=");
796
+ strappend_bin(str, buf, sizeof(buf));
797
+ }
798
+ #endif
799
+ #ifdef ARCHIVE_HAS_SHA384
800
+ if (mtree->compute_sum & F_SHA384) {
801
+ unsigned char buf[48];
802
+
803
+ archive_sha384_final(&mtree->sha384ctx, buf);
804
+ archive_strcat(str, " sha384digest=");
805
+ strappend_bin(str, buf, sizeof(buf));
806
+ }
807
+ #endif
808
+ #ifdef ARCHIVE_HAS_SHA512
809
+ if (mtree->compute_sum & F_SHA512) {
810
+ unsigned char buf[64];
811
+
812
+ archive_sha512_final(&mtree->sha512ctx, buf);
813
+ archive_strcat(str, " sha512digest=");
814
+ strappend_bin(str, buf, sizeof(buf));
815
+ }
816
+ #endif
817
+ archive_strcat(str, "\n");
818
+ if (mtree->indent)
819
+ mtree_indent(mtree);
820
+
821
+ archive_entry_free(entry);
822
+
823
+ if (mtree->buf.length > 32768) {
824
+ ret = (a->compressor.write)(a, mtree->buf.s, mtree->buf.length);
825
+ archive_string_empty(&mtree->buf);
826
+ } else
827
+ ret = ARCHIVE_OK;
828
+
829
+ return (ret == ARCHIVE_OK ? ret : ARCHIVE_FATAL);
830
+ }
831
+
832
+ static int
833
+ archive_write_mtree_finish(struct archive_write *a)
834
+ {
835
+ struct mtree_writer *mtree= a->format_data;
836
+
837
+ archive_write_set_bytes_in_last_block(&a->archive, 1);
838
+
839
+ return (a->compressor.write)(a, mtree->buf.s, mtree->buf.length);
840
+ }
841
+
842
+ static ssize_t
843
+ archive_write_mtree_data(struct archive_write *a, const void *buff, size_t n)
844
+ {
845
+ struct mtree_writer *mtree= a->format_data;
846
+
847
+ if (n > mtree->entry_bytes_remaining)
848
+ n = mtree->entry_bytes_remaining;
849
+ if (mtree->dironly)
850
+ /* We don't need compute a regular file sum */
851
+ return (n);
852
+ if (mtree->compute_sum & F_CKSUM) {
853
+ /*
854
+ * Compute a POSIX 1003.2 checksum
855
+ */
856
+ const unsigned char *p;
857
+ size_t nn;
858
+
859
+ for (nn = n, p = buff; nn--; ++p)
860
+ COMPUTE_CRC(mtree->crc, *p);
861
+ mtree->crc_len += n;
862
+ }
863
+ #ifdef ARCHIVE_HAS_MD5
864
+ if (mtree->compute_sum & F_MD5)
865
+ archive_md5_update(&mtree->md5ctx, buff, n);
866
+ #endif
867
+ #ifdef ARCHIVE_HAS_RMD160
868
+ if (mtree->compute_sum & F_RMD160)
869
+ archive_rmd160_update(&mtree->rmd160ctx, buff, n);
870
+ #endif
871
+ #ifdef ARCHIVE_HAS_SHA1
872
+ if (mtree->compute_sum & F_SHA1)
873
+ archive_sha1_update(&mtree->sha1ctx, buff, n);
874
+ #endif
875
+ #ifdef ARCHIVE_HAS_SHA256
876
+ if (mtree->compute_sum & F_SHA256)
877
+ archive_sha256_update(&mtree->sha256ctx, buff, n);
878
+ #endif
879
+ #ifdef ARCHIVE_HAS_SHA384
880
+ if (mtree->compute_sum & F_SHA384)
881
+ archive_sha384_update(&mtree->sha384ctx, buff, n);
882
+ #endif
883
+ #ifdef ARCHIVE_HAS_SHA512
884
+ if (mtree->compute_sum & F_SHA512)
885
+ archive_sha512_update(&mtree->sha512ctx, buff, n);
886
+ #endif
887
+ return (n);
888
+ }
889
+
890
+ static int
891
+ archive_write_mtree_destroy(struct archive_write *a)
892
+ {
893
+ struct mtree_writer *mtree= a->format_data;
894
+
895
+ if (mtree == NULL)
896
+ return (ARCHIVE_OK);
897
+
898
+ archive_entry_free(mtree->entry);
899
+ archive_string_free(&mtree->ebuf);
900
+ archive_string_free(&mtree->buf);
901
+ archive_string_free(&mtree->set.parent);
902
+ free(mtree);
903
+ a->format_data = NULL;
904
+ return (ARCHIVE_OK);
905
+ }
906
+
907
+ static int
908
+ archive_write_mtree_options(struct archive_write *a, const char *key,
909
+ const char *value)
910
+ {
911
+ struct mtree_writer *mtree= a->format_data;
912
+ int keybit = 0;
913
+
914
+ switch (key[0]) {
915
+ case 'a':
916
+ if (strcmp(key, "all") == 0)
917
+ keybit = ~0;
918
+ break;
919
+ case 'c':
920
+ if (strcmp(key, "cksum") == 0)
921
+ keybit = F_CKSUM;
922
+ break;
923
+ case 'd':
924
+ if (strcmp(key, "device") == 0)
925
+ keybit = F_DEV;
926
+ else if (strcmp(key, "dironly") == 0) {
927
+ mtree->dironly = (value != NULL)? 1: 0;
928
+ return (ARCHIVE_OK);
929
+ }
930
+ break;
931
+ case 'f':
932
+ if (strcmp(key, "flags") == 0)
933
+ keybit = F_FLAGS;
934
+ break;
935
+ case 'g':
936
+ if (strcmp(key, "gid") == 0)
937
+ keybit = F_GID;
938
+ else if (strcmp(key, "gname") == 0)
939
+ keybit = F_GNAME;
940
+ break;
941
+ case 'i':
942
+ if (strcmp(key, "indent") == 0) {
943
+ mtree->indent = (value != NULL)? 1: 0;
944
+ return (ARCHIVE_OK);
945
+ }
946
+ break;
947
+ case 'l':
948
+ if (strcmp(key, "link") == 0)
949
+ keybit = F_SLINK;
950
+ break;
951
+ case 'm':
952
+ if (strcmp(key, "md5") == 0 ||
953
+ strcmp(key, "md5digest") == 0)
954
+ keybit = F_MD5;
955
+ if (strcmp(key, "mode") == 0)
956
+ keybit = F_MODE;
957
+ break;
958
+ case 'n':
959
+ if (strcmp(key, "nlink") == 0)
960
+ keybit = F_NLINK;
961
+ break;
962
+ case 'r':
963
+ if (strcmp(key, "ripemd160digest") == 0 ||
964
+ strcmp(key, "rmd160") == 0 ||
965
+ strcmp(key, "rmd160digest") == 0)
966
+ keybit = F_RMD160;
967
+ break;
968
+ case 's':
969
+ if (strcmp(key, "sha1") == 0 ||
970
+ strcmp(key, "sha1digest") == 0)
971
+ keybit = F_SHA1;
972
+ if (strcmp(key, "sha256") == 0 ||
973
+ strcmp(key, "sha256digest") == 0)
974
+ keybit = F_SHA256;
975
+ if (strcmp(key, "sha384") == 0 ||
976
+ strcmp(key, "sha384digest") == 0)
977
+ keybit = F_SHA384;
978
+ if (strcmp(key, "sha512") == 0 ||
979
+ strcmp(key, "sha512digest") == 0)
980
+ keybit = F_SHA512;
981
+ if (strcmp(key, "size") == 0)
982
+ keybit = F_SIZE;
983
+ break;
984
+ case 't':
985
+ if (strcmp(key, "time") == 0)
986
+ keybit = F_TIME;
987
+ else if (strcmp(key, "type") == 0)
988
+ keybit = F_TYPE;
989
+ break;
990
+ case 'u':
991
+ if (strcmp(key, "uid") == 0)
992
+ keybit = F_UID;
993
+ else if (strcmp(key, "uname") == 0)
994
+ keybit = F_UNAME;
995
+ else if (strcmp(key, "use-set") == 0) {
996
+ mtree->set.output = (value != NULL)? 1: 0;
997
+ return (ARCHIVE_OK);
998
+ }
999
+ break;
1000
+ }
1001
+ if (keybit != 0) {
1002
+ if (value != NULL)
1003
+ mtree->keys |= keybit;
1004
+ else
1005
+ mtree->keys &= ~keybit;
1006
+ return (ARCHIVE_OK);
1007
+ }
1008
+
1009
+ return (ARCHIVE_WARN);
1010
+ }
1011
+
1012
+ int
1013
+ archive_write_set_format_mtree(struct archive *_a)
1014
+ {
1015
+ struct archive_write *a = (struct archive_write *)_a;
1016
+ struct mtree_writer *mtree;
1017
+
1018
+ if (a->format_destroy != NULL)
1019
+ (a->format_destroy)(a);
1020
+
1021
+ if ((mtree = malloc(sizeof(*mtree))) == NULL) {
1022
+ archive_set_error(&a->archive, ENOMEM,
1023
+ "Can't allocate mtree data");
1024
+ return (ARCHIVE_FATAL);
1025
+ }
1026
+
1027
+ mtree->entry = NULL;
1028
+ mtree->first = 1;
1029
+ memset(&(mtree->set), 0, sizeof(mtree->set));
1030
+ archive_string_init(&mtree->set.parent);
1031
+ mtree->keys = DEFAULT_KEYS;
1032
+ mtree->dironly = 0;
1033
+ mtree->indent = 0;
1034
+ archive_string_init(&mtree->ebuf);
1035
+ archive_string_init(&mtree->buf);
1036
+ a->format_data = mtree;
1037
+ a->format_destroy = archive_write_mtree_destroy;
1038
+
1039
+ a->pad_uncompressed = 0;
1040
+ a->format_name = "mtree";
1041
+ a->format_options = archive_write_mtree_options;
1042
+ a->format_write_header = archive_write_mtree_header;
1043
+ a->format_finish = archive_write_mtree_finish;
1044
+ a->format_write_data = archive_write_mtree_data;
1045
+ a->format_finish_entry = archive_write_mtree_finish_entry;
1046
+ a->archive.archive_format = ARCHIVE_FORMAT_MTREE;
1047
+ a->archive.archive_format_name = "mtree";
1048
+
1049
+ return (ARCHIVE_OK);
1050
+ }