]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - contrib/libarchive/libarchive/archive_write_set_format_raw.c
MFC r299529,r299540,r299576,r299896:
[FreeBSD/stable/10.git] / contrib / libarchive / libarchive / archive_write_set_format_raw.c
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
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         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
82 static int
83 archive_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
104 static ssize_t
105 archive_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
116 static int
117 archive_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 }