1299425Smm/*-
2299425Smm * Copyright (c) 2013 Marek Kubica
3299425Smm * All rights reserved.
4299425Smm *
5299425Smm * Redistribution and use in source and binary forms, with or without
6299425Smm * modification, are permitted provided that the following conditions
7299425Smm * are met:
8299425Smm * 1. Redistributions of source code must retain the above copyright
9299425Smm *    notice, this list of conditions and the following disclaimer.
10299425Smm * 2. Redistributions in binary form must reproduce the above copyright
11299425Smm *    notice, this list of conditions and the following disclaimer in the
12299425Smm *    documentation and/or other materials provided with the distribution.
13299425Smm *
14299425Smm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
15299425Smm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16299425Smm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17299425Smm * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
18299425Smm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19299425Smm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20299425Smm * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21299425Smm * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22299425Smm * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23299425Smm * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24299425Smm */
25299425Smm
26299425Smm#include "archive_platform.h"
27299425Smm
28299425Smm#ifdef HAVE_ERRNO_H
29299425Smm#include <errno.h>
30299425Smm#endif
31299425Smm
32299425Smm#include "archive_entry.h"
33299425Smm#include "archive_write_private.h"
34299425Smm
35299425Smmstatic ssize_t	archive_write_raw_data(struct archive_write *,
36299425Smm		    const void *buff, size_t s);
37299425Smmstatic int	archive_write_raw_free(struct archive_write *);
38299425Smmstatic int	archive_write_raw_header(struct archive_write *,
39299425Smm		    struct archive_entry *);
40299425Smm
41299425Smmstruct raw {
42299425Smm        int entries_written;
43299425Smm};
44299425Smm
45299425Smm/*
46299425Smm * Set output format to 'raw' format.
47299425Smm */
48299425Smmint
49299425Smmarchive_write_set_format_raw(struct archive *_a)
50299425Smm{
51299425Smm	struct archive_write *a = (struct archive_write *)_a;
52299425Smm	struct raw *raw;
53299425Smm
54299425Smm	archive_check_magic(_a, ARCHIVE_WRITE_MAGIC,
55299425Smm	    ARCHIVE_STATE_NEW, "archive_write_set_format_raw");
56299425Smm
57299425Smm	/* If someone else was already registered, unregister them. */
58299425Smm	if (a->format_free != NULL)
59299425Smm		(a->format_free)(a);
60299425Smm
61299425Smm	raw = (struct raw *)calloc(1, sizeof(*raw));
62299425Smm	if (raw == NULL) {
63299425Smm		archive_set_error(&a->archive, ENOMEM, "Can't allocate raw data");
64299425Smm		return (ARCHIVE_FATAL);
65299425Smm	}
66299425Smm	raw->entries_written = 0;
67299425Smm	a->format_data = raw;
68299425Smm	a->format_name = "raw";
69299425Smm        /* no options exist for this format */
70299425Smm	a->format_options = NULL;
71299425Smm	a->format_write_header = archive_write_raw_header;
72299425Smm	a->format_write_data = archive_write_raw_data;
73299425Smm	a->format_finish_entry = NULL;
74299425Smm        /* nothing needs to be done on closing */
75299425Smm	a->format_close = NULL;
76299425Smm	a->format_free = archive_write_raw_free;
77299425Smm	a->archive.archive_format = ARCHIVE_FORMAT_RAW;
78299425Smm	a->archive.archive_format_name = "RAW";
79299425Smm	return (ARCHIVE_OK);
80299425Smm}
81299425Smm
82299425Smmstatic int
83299425Smmarchive_write_raw_header(struct archive_write *a, struct archive_entry *entry)
84299425Smm{
85299425Smm	struct raw *raw = (struct raw *)a->format_data;
86299425Smm
87299425Smm	if (archive_entry_filetype(entry) != AE_IFREG) {
88299425Smm		archive_set_error(&a->archive, ERANGE,
89299425Smm		    "Raw format only supports filetype AE_IFREG");
90299425Smm		return (ARCHIVE_FATAL);
91299425Smm	}
92299425Smm
93299425Smm
94299425Smm	if (raw->entries_written > 0) {
95299425Smm		archive_set_error(&a->archive, ERANGE,
96299425Smm		    "Raw format only supports one entry per archive");
97299425Smm		return (ARCHIVE_FATAL);
98299425Smm	}
99299425Smm	raw->entries_written++;
100299425Smm
101299425Smm	return (ARCHIVE_OK);
102299425Smm}
103299425Smm
104299425Smmstatic ssize_t
105299425Smmarchive_write_raw_data(struct archive_write *a, const void *buff, size_t s)
106299425Smm{
107299425Smm	int ret;
108299425Smm
109299425Smm	ret = __archive_write_output(a, buff, s);
110299425Smm	if (ret >= 0)
111299425Smm		return (s);
112299425Smm	else
113299425Smm		return (ret);
114299425Smm}
115299425Smm
116299425Smmstatic int
117299425Smmarchive_write_raw_free(struct archive_write *a)
118299425Smm{
119299425Smm	struct raw *raw;
120299425Smm
121299425Smm	raw = (struct raw *)a->format_data;
122299425Smm	free(raw);
123299425Smm	a->format_data = NULL;
124299425Smm	return (ARCHIVE_OK);
125299425Smm}
126