1/*-
2 * Copyright (c) 2003-2007 Tim Kientzle
3 * Copyright (c) 2011-2012 Michihiro NAKAJIMA
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: stable/11/contrib/libarchive/libarchive/archive_write_set_format_cpio_binary.c 370535 2021-09-10 08:34:36Z git2svn $");
29
30#ifdef HAVE_ERRNO_H
31#include <errno.h>
32#endif
33#include <stdio.h>
34#ifdef HAVE_STDLIB_H
35#include <stdlib.h>
36#endif
37#ifdef HAVE_STRING_H
38#include <string.h>
39#endif
40
41#include "archive.h"
42#include "archive_entry.h"
43#include "archive_entry_locale.h"
44#include "archive_private.h"
45#include "archive_write_private.h"
46#include "archive_write_set_format_private.h"
47
48static ssize_t	archive_write_binary_data(struct archive_write *,
49		    const void *buff, size_t s);
50static int	archive_write_binary_close(struct archive_write *);
51static int	archive_write_binary_free(struct archive_write *);
52static int	archive_write_binary_finish_entry(struct archive_write *);
53static int	archive_write_binary_header(struct archive_write *,
54		    struct archive_entry *);
55static int	archive_write_binary_options(struct archive_write *,
56		    const char *, const char *);
57static int	write_header(struct archive_write *, struct archive_entry *);
58
59struct cpio {
60	uint64_t	  entry_bytes_remaining;
61
62	int64_t		  ino_next;
63
64	struct		 { int64_t old; int new;} *ino_list;
65	size_t		  ino_list_size;
66	size_t		  ino_list_next;
67
68	struct archive_string_conv *opt_sconv;
69	struct archive_string_conv *sconv_default;
70	int		  init_default_conversion;
71};
72
73/* This struct needs to be packed to get the header right */
74
75#if defined(__GNUC__)
76#define PACKED(x) x __attribute__((packed))
77#elif defined(_MSC_VER)
78#define PACKED(x) __pragma(pack(push, 1)) x __pragma(pack(pop))
79#else
80#define PACKED(x) x
81#endif
82
83#define HSIZE 26
84
85PACKED(struct cpio_binary_header {
86	uint16_t	h_magic;
87	uint16_t	h_dev;
88	uint16_t	h_ino;
89	uint16_t	h_mode;
90	uint16_t	h_uid;
91	uint16_t	h_gid;
92	uint16_t	h_nlink;
93	uint16_t	h_majmin;
94	uint32_t	h_mtime;
95	uint16_t	h_namesize;
96	uint32_t	h_filesize;
97});
98
99/* Back in the day, the 7th Edition cpio.c had this, to
100 * adapt to, as the comment said, "VAX, Interdata, ...":
101 *
102 * union { long l; short s[2]; char c[4]; } U;
103 * #define MKSHORT(v,lv) {U.l=1L;if(U.c[0]) U.l=lv,v[0]=U.s[1],v[1]=U.s[0]; else U.l=lv,v[0]=U.s[0],v[1]=U.s[1];}
104 * long mklong(v)
105 * short v[];
106 * {
107 *         U.l = 1;
108 *         if(U.c[0])
109 *                 U.s[0] = v[1], U.s[1] = v[0];
110 *         else
111 *                 U.s[0] = v[0], U.s[1] = v[1];
112 *         return U.l;
113 * }
114 *
115 * Of course, that assumes that all machines have little-endian shorts,
116 * and just adapts the others to the special endianness of the PDP-11.
117 *
118 * Now, we could do this:
119 *
120 * union { uint32_t l; uint16_t s[2]; uint8_t c[4]; } U;
121 * #define PUTI16(v,sv) {U.s[0]=1;if(U.c[0]) v=sv; else U.s[0]=sv,U.c[2]=U.c[1],U.c[3]=U.c[0],v=U.s[1];}
122 * #define PUTI32(v,lv) {char_t Ut;U.l=1;if(U.c[0]) U.l=lv,v[0]=U.s[1],v[1]=U.s[0]; else U.l=lv,Ut=U.c[0],U.c[0]=U.c[1],U.c[1]=Ut,Ut=U.c[2],U.c[2]=U.c[3],U.c[3]=Ut,v[0]=U.s[0],v[1]=U.s[1];}
123 *
124 * ...but it feels a little better to do it like this:
125 */
126
127static uint16_t swap16(uint16_t in) {
128	union {
129		uint16_t s[2];
130		uint8_t c[4];
131	} U;
132	U.s[0] = 1;
133	if (U.c[0])
134		return in;
135	else {
136		U.s[0] = in;
137		U.c[2] = U.c[1];
138		U.c[3] = U.c[0];
139		return U.s[1];
140	}
141	/* NOTREACHED */
142}
143
144static uint32_t swap32(uint32_t in) {
145	union {
146		uint32_t l;
147		uint16_t s[2];
148		uint8_t c[4];
149	} U;
150	U.l = 1;
151	if (U.c[0]) {		/* Little-endian */
152		uint16_t t;
153		U.l = in;
154		t = U.s[0];
155		U.s[0] = U.s[1];
156		U.s[1] = t;
157	} else if (U.c[3]) {	/* Big-endian */
158		U.l = in;
159		U.s[0] = swap16(U.s[0]);
160		U.s[1] = swap16(U.s[1]);
161	} else {		/* PDP-endian */
162		U.l = in;
163	}
164	return U.l;
165}
166
167/*
168 * Set output format to the selected binary variant
169 */
170static int
171archive_write_set_format_cpio_binary(struct archive *_a, int format)
172{
173	struct archive_write *a = (struct archive_write *)_a;
174	struct cpio *cpio;
175
176	if (sizeof(struct cpio_binary_header) != HSIZE) {
177		archive_set_error(&a->archive, EINVAL,
178				  "Binary cpio format not supported on this platform");
179		return (ARCHIVE_FATAL);
180	}
181
182	archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
183	    ARCHIVE_STATE_NEW, "archive_write_set_format_cpio_binary");
184
185	/* If someone else was already registered, unregister them. */
186	if (a->format_free != NULL)
187		(a->format_free)(a);
188
189	cpio = (struct cpio *)calloc(1, sizeof(*cpio));
190	if (cpio == NULL) {
191		archive_set_error(&a->archive, ENOMEM, "Can't allocate cpio data");
192		return (ARCHIVE_FATAL);
193	}
194	a->format_data = cpio;
195	a->format_name = "cpio";
196	a->format_options = archive_write_binary_options;
197	a->format_write_header = archive_write_binary_header;
198	a->format_write_data = archive_write_binary_data;
199	a->format_finish_entry = archive_write_binary_finish_entry;
200	a->format_close = archive_write_binary_close;
201	a->format_free = archive_write_binary_free;
202	a->archive.archive_format = format;
203	switch (format) {
204	case ARCHIVE_FORMAT_CPIO_PWB:
205		a->archive.archive_format_name = "PWB cpio";
206		break;
207	case ARCHIVE_FORMAT_CPIO_BIN_LE:
208		a->archive.archive_format_name = "7th Edition cpio";
209		break;
210	default:
211		archive_set_error(&a->archive, EINVAL, "binary format must be 'pwb' or 'bin'");
212		return (ARCHIVE_FATAL);
213	}
214	return (ARCHIVE_OK);
215}
216
217/*
218 * Set output format to PWB (6th Edition) binary format
219 */
220int
221archive_write_set_format_cpio_pwb(struct archive *_a)
222{
223	return archive_write_set_format_cpio_binary(_a, ARCHIVE_FORMAT_CPIO_PWB);
224}
225
226/*
227 * Set output format to 7th Edition binary format
228 */
229int
230archive_write_set_format_cpio_bin(struct archive *_a)
231{
232	return archive_write_set_format_cpio_binary(_a, ARCHIVE_FORMAT_CPIO_BIN_LE);
233}
234
235static int
236archive_write_binary_options(struct archive_write *a, const char *key,
237    const char *val)
238{
239	struct cpio *cpio = (struct cpio *)a->format_data;
240	int ret = ARCHIVE_FAILED;
241
242	if (strcmp(key, "hdrcharset")  == 0) {
243		if (val == NULL || val[0] == 0)
244			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
245			    "%s: hdrcharset option needs a character-set name",
246			    a->format_name);
247		else {
248			cpio->opt_sconv = archive_string_conversion_to_charset(
249			    &a->archive, val, 0);
250			if (cpio->opt_sconv != NULL)
251				ret = ARCHIVE_OK;
252			else
253				ret = ARCHIVE_FATAL;
254		}
255		return (ret);
256	}
257
258	/* Note: The "warn" return is just to inform the options
259	 * supervisor that we didn't handle it.  It will generate
260	 * a suitable error if no one used this option. */
261	return (ARCHIVE_WARN);
262}
263
264/*
265 * Ino values are as long as 64 bits on some systems; cpio format
266 * only allows 16 bits and relies on the ino values to identify hardlinked
267 * files.  So, we can't merely "hash" the ino numbers since collisions
268 * would corrupt the archive.  Instead, we generate synthetic ino values
269 * to store in the archive and maintain a map of original ino values to
270 * synthetic ones so we can preserve hardlink information.
271 *
272 * TODO: Make this more efficient.  It's not as bad as it looks (most
273 * files don't have any hardlinks and we don't do any work here for those),
274 * but it wouldn't be hard to do better.
275 *
276 * TODO: Work with dev/ino pairs here instead of just ino values.
277 */
278static int
279synthesize_ino_value(struct cpio *cpio, struct archive_entry *entry)
280{
281	int64_t ino = archive_entry_ino64(entry);
282	int ino_new;
283	size_t i;
284
285	/*
286	 * If no index number was given, don't assign one.  In
287	 * particular, this handles the end-of-archive marker
288	 * correctly by giving it a zero index value.  (This is also
289	 * why we start our synthetic index numbers with one below.)
290	 */
291	if (ino == 0)
292		return (0);
293
294	/* Don't store a mapping if we don't need to. */
295	if (archive_entry_nlink(entry) < 2) {
296		return (int)(++cpio->ino_next);
297	}
298
299	/* Look up old ino; if we have it, this is a hardlink
300	 * and we reuse the same value. */
301	for (i = 0; i < cpio->ino_list_next; ++i) {
302		if (cpio->ino_list[i].old == ino)
303			return (cpio->ino_list[i].new);
304	}
305
306	/* Assign a new index number. */
307	ino_new = (int)(++cpio->ino_next);
308
309	/* Ensure space for the new mapping. */
310	if (cpio->ino_list_size <= cpio->ino_list_next) {
311		size_t newsize = cpio->ino_list_size < 512
312		    ? 512 : cpio->ino_list_size * 2;
313		void *newlist = realloc(cpio->ino_list,
314		    sizeof(cpio->ino_list[0]) * newsize);
315		if (newlist == NULL)
316			return (-1);
317
318		cpio->ino_list_size = newsize;
319		cpio->ino_list = newlist;
320	}
321
322	/* Record and return the new value. */
323	cpio->ino_list[cpio->ino_list_next].old = ino;
324	cpio->ino_list[cpio->ino_list_next].new = ino_new;
325	++cpio->ino_list_next;
326	return (ino_new);
327}
328
329
330static struct archive_string_conv *
331get_sconv(struct archive_write *a)
332{
333	struct cpio *cpio;
334	struct archive_string_conv *sconv;
335
336	cpio = (struct cpio *)a->format_data;
337	sconv = cpio->opt_sconv;
338	if (sconv == NULL) {
339		if (!cpio->init_default_conversion) {
340			cpio->sconv_default =
341			    archive_string_default_conversion_for_write(
342			      &(a->archive));
343			cpio->init_default_conversion = 1;
344		}
345		sconv = cpio->sconv_default;
346	}
347	return (sconv);
348}
349
350static int
351archive_write_binary_header(struct archive_write *a, struct archive_entry *entry)
352{
353	const char *path;
354	size_t len;
355
356	if (archive_entry_filetype(entry) == 0 && archive_entry_hardlink(entry) == NULL) {
357		archive_set_error(&a->archive, -1, "Filetype required");
358		return (ARCHIVE_FAILED);
359	}
360
361	if (archive_entry_pathname_l(entry, &path, &len, get_sconv(a)) != 0
362	    && errno == ENOMEM) {
363		archive_set_error(&a->archive, ENOMEM,
364		    "Can't allocate memory for Pathname");
365		return (ARCHIVE_FATAL);
366	}
367	if (len == 0 || path == NULL || path[0] == '\0') {
368		archive_set_error(&a->archive, -1, "Pathname required");
369		return (ARCHIVE_FAILED);
370	}
371
372	if (!archive_entry_size_is_set(entry) || archive_entry_size(entry) < 0) {
373		archive_set_error(&a->archive, -1, "Size required");
374		return (ARCHIVE_FAILED);
375	}
376	return write_header(a, entry);
377}
378
379static int
380write_header(struct archive_write *a, struct archive_entry *entry)
381{
382	struct cpio *cpio;
383	const char *p, *path;
384	int pathlength, ret, ret_final;
385	int64_t	ino;
386	struct cpio_binary_header h;
387	struct archive_string_conv *sconv;
388	struct archive_entry *entry_main;
389	size_t len;
390
391	cpio = (struct cpio *)a->format_data;
392	ret_final = ARCHIVE_OK;
393	sconv = get_sconv(a);
394
395#if defined(_WIN32) && !defined(__CYGWIN__)
396	/* Make sure the path separators in pathname, hardlink and symlink
397	 * are all slash '/', not the Windows path separator '\'. */
398	entry_main = __la_win_entry_in_posix_pathseparator(entry);
399	if (entry_main == NULL) {
400		archive_set_error(&a->archive, ENOMEM,
401		    "Can't allocate ustar data");
402		return(ARCHIVE_FATAL);
403	}
404	if (entry != entry_main)
405		entry = entry_main;
406	else
407		entry_main = NULL;
408#else
409	entry_main = NULL;
410#endif
411
412	ret = archive_entry_pathname_l(entry, &path, &len, sconv);
413	if (ret != 0) {
414		if (errno == ENOMEM) {
415			archive_set_error(&a->archive, ENOMEM,
416			    "Can't allocate memory for Pathname");
417			ret_final = ARCHIVE_FATAL;
418			goto exit_write_header;
419		}
420		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
421		    "Can't translate pathname '%s' to %s",
422		    archive_entry_pathname(entry),
423		    archive_string_conversion_charset_name(sconv));
424		ret_final = ARCHIVE_WARN;
425	}
426	/* Include trailing null */
427	pathlength = (int)len + 1;
428
429	h.h_magic = swap16(070707);
430	h.h_dev = swap16(archive_entry_dev(entry));
431
432	ino = synthesize_ino_value(cpio, entry);
433	if (ino < 0) {
434		archive_set_error(&a->archive, ENOMEM,
435		    "No memory for ino translation table");
436		ret_final = ARCHIVE_FATAL;
437		goto exit_write_header;
438	} else if (ino > 077777) {
439		archive_set_error(&a->archive, ERANGE,
440		    "Too many files for this cpio format");
441		ret_final = ARCHIVE_FATAL;
442		goto exit_write_header;
443	}
444	h.h_ino = swap16(ino);
445
446	h.h_mode = archive_entry_mode(entry);
447	if (((h.h_mode & AE_IFMT) == AE_IFSOCK) || ((h.h_mode & AE_IFMT) == AE_IFIFO)) {
448		archive_set_error(&a->archive, EINVAL,
449				  "sockets and fifos cannot be represented in the binary cpio formats");
450		ret_final = ARCHIVE_FATAL;
451		goto exit_write_header;
452	}
453	if (a->archive.archive_format == ARCHIVE_FORMAT_CPIO_PWB) {
454		if ((h.h_mode & AE_IFMT) == AE_IFLNK) {
455			archive_set_error(&a->archive, EINVAL,
456					  "symbolic links cannot be represented in the PWB cpio format");
457			ret_final = ARCHIVE_FATAL;
458			goto exit_write_header;
459		}
460		/* we could turn off AE_IFREG here, but it does no harm, */
461		/* and allows v7 cpio to read the entry without confusion */
462	}
463	h.h_mode = swap16(h.h_mode);
464
465	h.h_uid = swap16(archive_entry_uid(entry));
466	h.h_gid = swap16(archive_entry_gid(entry));
467	h.h_nlink = swap16(archive_entry_nlink(entry));
468
469	if (archive_entry_filetype(entry) == AE_IFBLK
470	    || archive_entry_filetype(entry) == AE_IFCHR)
471		h.h_majmin = swap16(archive_entry_rdev(entry));
472	else
473		h.h_majmin = 0;
474
475	h.h_mtime = swap32(archive_entry_mtime(entry));
476	h.h_namesize = swap16(pathlength);
477
478	/* Non-regular files don't store bodies. */
479	if (archive_entry_filetype(entry) != AE_IFREG)
480		archive_entry_set_size(entry, 0);
481
482	/* Symlinks get the link written as the body of the entry. */
483	ret = archive_entry_symlink_l(entry, &p, &len, sconv);
484	if (ret != 0) {
485		if (errno == ENOMEM) {
486			archive_set_error(&a->archive, ENOMEM,
487			    "Can't allocate memory for Linkname");
488			ret_final = ARCHIVE_FATAL;
489			goto exit_write_header;
490		}
491		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
492		    "Can't translate linkname '%s' to %s",
493		    archive_entry_symlink(entry),
494		    archive_string_conversion_charset_name(sconv));
495		ret_final = ARCHIVE_WARN;
496	}
497
498	if (len > 0 && p != NULL  &&  *p != '\0') {
499		if (a->archive.archive_format == ARCHIVE_FORMAT_CPIO_PWB) {
500			archive_set_error(&a->archive, EINVAL,
501					  "symlinks are not supported by UNIX V6 or by PWB cpio");
502			ret_final = ARCHIVE_FATAL;
503			goto exit_write_header;
504		}
505		h.h_filesize = swap32(strlen(p)); /* symlink */
506	} else {
507		if ((a->archive.archive_format == ARCHIVE_FORMAT_CPIO_PWB) &&
508		    (archive_entry_size(entry) > 256*256*256-1)) {
509			archive_set_error(&a->archive, ERANGE,
510					  "File is too large for PWB binary cpio format.");
511			ret_final = ARCHIVE_FAILED;
512			goto exit_write_header;
513		} else if (archive_entry_size(entry) > INT32_MAX) {
514			archive_set_error(&a->archive, ERANGE,
515					  "File is too large for binary cpio format.");
516			ret_final = ARCHIVE_FAILED;
517			goto exit_write_header;
518		}
519		h.h_filesize = swap32(archive_entry_size(entry)); /* file */
520	}
521
522	ret = __archive_write_output(a, &h, HSIZE);
523	if (ret != ARCHIVE_OK) {
524		ret_final = ARCHIVE_FATAL;
525		goto exit_write_header;
526	}
527
528	ret = __archive_write_output(a, path, pathlength);
529	if ((ret == ARCHIVE_OK) && ((pathlength % 2) != 0))
530		ret = __archive_write_nulls(a, 1);
531	if (ret != ARCHIVE_OK) {
532		ret_final = ARCHIVE_FATAL;
533		goto exit_write_header;
534	}
535
536	cpio->entry_bytes_remaining = archive_entry_size(entry);
537	if ((cpio->entry_bytes_remaining % 2) != 0)
538		cpio->entry_bytes_remaining++;
539
540	/* Write the symlink now. */
541	if (p != NULL  &&  *p != '\0') {
542		ret = __archive_write_output(a, p, strlen(p));
543		if ((ret == ARCHIVE_OK) && ((strlen(p) % 2) != 0))
544			ret = __archive_write_nulls(a, 1);
545		if (ret != ARCHIVE_OK) {
546			ret_final = ARCHIVE_FATAL;
547			goto exit_write_header;
548		}
549	}
550
551exit_write_header:
552	archive_entry_free(entry_main);
553	return (ret_final);
554}
555
556static ssize_t
557archive_write_binary_data(struct archive_write *a, const void *buff, size_t s)
558{
559	struct cpio *cpio;
560	int ret;
561
562	cpio = (struct cpio *)a->format_data;
563	if (s > cpio->entry_bytes_remaining)
564		s = (size_t)cpio->entry_bytes_remaining;
565
566	ret = __archive_write_output(a, buff, s);
567	cpio->entry_bytes_remaining -= s;
568	if (ret >= 0)
569		return (s);
570	else
571		return (ret);
572}
573
574static int
575archive_write_binary_close(struct archive_write *a)
576{
577	int er;
578	struct archive_entry *trailer;
579
580	trailer = archive_entry_new2(NULL);
581	/* nlink = 1 here for GNU cpio compat. */
582	archive_entry_set_nlink(trailer, 1);
583	archive_entry_set_size(trailer, 0);
584	archive_entry_set_pathname(trailer, "TRAILER!!!");
585	er = write_header(a, trailer);
586	archive_entry_free(trailer);
587	return (er);
588}
589
590static int
591archive_write_binary_free(struct archive_write *a)
592{
593	struct cpio *cpio;
594
595	cpio = (struct cpio *)a->format_data;
596	free(cpio->ino_list);
597	free(cpio);
598	a->format_data = NULL;
599	return (ARCHIVE_OK);
600}
601
602static int
603archive_write_binary_finish_entry(struct archive_write *a)
604{
605	struct cpio *cpio;
606
607	cpio = (struct cpio *)a->format_data;
608	return (__archive_write_nulls(a,
609		(size_t)cpio->entry_bytes_remaining));
610}
611