xref: /freebsd/contrib/libarchive/libarchive/archive_write_set_format_raw.c (revision 185becb1e1bd2657c156f78aeb52edac05ba5fb5)
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 
35 static ssize_t	archive_write_raw_data(struct archive_write *,
36 		    const void *buff, size_t s);
37 static int	archive_write_raw_free(struct archive_write *);
38 static int	archive_write_raw_header(struct archive_write *,
39 		    struct archive_entry *);
40 
41 struct raw {
42         int entries_written;
43 };
44 
45 /*
46  * Set output format to 'raw' format.
47  */
48 int
archive_write_set_format_raw(struct archive * _a)49 archive_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 	(void)__archive_write_unregister_format(a);
59 
60 	raw = calloc(1, sizeof(*raw));
61 	if (raw == NULL) {
62 		archive_set_error(&a->archive, ENOMEM, "Can't allocate raw data");
63 		return (ARCHIVE_FATAL);
64 	}
65 	raw->entries_written = 0;
66 	a->format_data = raw;
67 	a->format_name = "raw";
68         /* no options exist for this format */
69 	a->format_options = NULL;
70 	a->format_write_header = archive_write_raw_header;
71 	a->format_write_data = archive_write_raw_data;
72 	a->format_finish_entry = NULL;
73         /* nothing needs to be done on closing */
74 	a->format_close = NULL;
75 	a->format_free = archive_write_raw_free;
76 	a->archive.archive_format = ARCHIVE_FORMAT_RAW;
77 	a->archive.archive_format_name = "RAW";
78 	return (ARCHIVE_OK);
79 }
80 
81 static int
archive_write_raw_header(struct archive_write * a,struct archive_entry * entry)82 archive_write_raw_header(struct archive_write *a, struct archive_entry *entry)
83 {
84 	struct raw *raw = a->format_data;
85 
86 	if (archive_entry_filetype(entry) != AE_IFREG) {
87 		archive_set_error(&a->archive, ERANGE,
88 		    "Raw format only supports filetype AE_IFREG");
89 		return (ARCHIVE_FATAL);
90 	}
91 
92 
93 	if (raw->entries_written > 0) {
94 		archive_set_error(&a->archive, ERANGE,
95 		    "Raw format only supports one entry per archive");
96 		return (ARCHIVE_FATAL);
97 	}
98 	raw->entries_written++;
99 
100 	return (ARCHIVE_OK);
101 }
102 
103 static ssize_t
archive_write_raw_data(struct archive_write * a,const void * buff,size_t s)104 archive_write_raw_data(struct archive_write *a, const void *buff, size_t s)
105 {
106 	int ret;
107 
108 	ret = __archive_write_output(a, buff, s);
109 	if (ret >= 0)
110 		return (s);
111 	else
112 		return (ret);
113 }
114 
115 static int
archive_write_raw_free(struct archive_write * a)116 archive_write_raw_free(struct archive_write *a)
117 {
118 	struct raw *raw = a->format_data;
119 
120 	free(raw);
121 	a->format_data = NULL;
122 	return (ARCHIVE_OK);
123 }
124