1/*-
2 * Copyright (c) 2013 Marek Kubica
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "archive_platform.h"
27
28#ifdef HAVE_ERRNO_H
29#include <errno.h>
30#endif
31
32#include "archive_entry.h"
33#include "archive_write_private.h"
34
35static ssize_t	archive_write_raw_data(struct archive_write *,
36		    const void *buff, size_t s);
37static int	archive_write_raw_free(struct archive_write *);
38static int	archive_write_raw_header(struct archive_write *,
39		    struct archive_entry *);
40
41struct raw {
42        int entries_written;
43};
44
45/*
46 * Set output format to 'raw' format.
47 */
48int
49archive_write_set_format_raw(struct archive *_a)
50{
51	struct archive_write *a = (struct archive_write *)_a;
52	struct raw *raw;
53
54	archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
55	    ARCHIVE_STATE_NEW, "archive_write_set_format_raw");
56
57	/* If someone else was already registered, unregister them. */
58	if (a->format_free != NULL)
59		(a->format_free)(a);
60
61	raw = (struct raw *)calloc(1, sizeof(*raw));
62	if (raw == NULL) {
63		archive_set_error(&a->archive, ENOMEM, "Can't allocate raw data");
64		return (ARCHIVE_FATAL);
65	}
66	raw->entries_written = 0;
67	a->format_data = raw;
68	a->format_name = "raw";
69        /* no options exist for this format */
70	a->format_options = NULL;
71	a->format_write_header = archive_write_raw_header;
72	a->format_write_data = archive_write_raw_data;
73	a->format_finish_entry = NULL;
74        /* nothing needs to be done on closing */
75	a->format_close = NULL;
76	a->format_free = archive_write_raw_free;
77	a->archive.archive_format = ARCHIVE_FORMAT_RAW;
78	a->archive.archive_format_name = "RAW";
79	return (ARCHIVE_OK);
80}
81
82static int
83archive_write_raw_header(struct archive_write *a, struct archive_entry *entry)
84{
85	struct raw *raw = (struct raw *)a->format_data;
86
87	if (archive_entry_filetype(entry) != AE_IFREG) {
88		archive_set_error(&a->archive, ERANGE,
89		    "Raw format only supports filetype AE_IFREG");
90		return (ARCHIVE_FATAL);
91	}
92
93
94	if (raw->entries_written > 0) {
95		archive_set_error(&a->archive, ERANGE,
96		    "Raw format only supports one entry per archive");
97		return (ARCHIVE_FATAL);
98	}
99	raw->entries_written++;
100
101	return (ARCHIVE_OK);
102}
103
104static ssize_t
105archive_write_raw_data(struct archive_write *a, const void *buff, size_t s)
106{
107	int ret;
108
109	ret = __archive_write_output(a, buff, s);
110	if (ret >= 0)
111		return (s);
112	else
113		return (ret);
114}
115
116static int
117archive_write_raw_free(struct archive_write *a)
118{
119	struct raw *raw;
120
121	raw = (struct raw *)a->format_data;
122	free(raw);
123	a->format_data = NULL;
124	return (ARCHIVE_OK);
125}
126