• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
2 
3 /*
4  * Copyright (C) 2014 Rob Clark <robclark@freedesktop.org>
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice (including the next
14  * paragraph) shall be included in all copies or substantial portions of the
15  * Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23  * SOFTWARE.
24  *
25  * Authors:
26  *    Rob Clark <robclark@freedesktop.org>
27  */
28 
29 #include <stdlib.h>
30 #include <string.h>
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #include <fcntl.h>
34 #include <archive.h>
35 #include <archive_entry.h>
36 
37 #include "io.h"
38 
39 struct io {
40 	struct archive *a;
41 	struct archive_entry *entry;
42 	unsigned offset;
43 };
44 
io_error(struct io * io)45 static void io_error(struct io *io)
46 {
47 	fprintf(stderr, "%s\n", archive_error_string(io->a));
48 	io_close(io);
49 }
50 
io_new(void)51 static struct io * io_new(void)
52 {
53 	struct io *io = calloc(1, sizeof(*io));
54 	int ret;
55 
56 	if (!io)
57 		return NULL;
58 
59 	io->a = archive_read_new();
60 	ret = archive_read_support_filter_gzip(io->a);
61 	if (ret != ARCHIVE_OK) {
62 		io_error(io);
63 		return NULL;
64 	}
65 
66 	ret = archive_read_support_filter_none(io->a);
67 	if (ret != ARCHIVE_OK) {
68 		io_error(io);
69 		return NULL;
70 	}
71 
72 	ret = archive_read_support_format_all(io->a);
73 	if (ret != ARCHIVE_OK) {
74 		io_error(io);
75 		return NULL;
76 	}
77 
78 	ret = archive_read_support_format_raw(io->a);
79 	if (ret != ARCHIVE_OK) {
80 		io_error(io);
81 		return NULL;
82 	}
83 
84 	return io;
85 }
86 
io_open(const char * filename)87 struct io * io_open(const char *filename)
88 {
89 	struct io *io = io_new();
90 	int ret;
91 
92 	if (!io)
93 		return NULL;
94 
95 	ret = archive_read_open_filename(io->a, filename, 10240);
96 	if (ret != ARCHIVE_OK) {
97 		io_error(io);
98 		return NULL;
99 	}
100 
101 	ret = archive_read_next_header(io->a, &io->entry);
102 	if (ret != ARCHIVE_OK) {
103 		io_error(io);
104 		return NULL;
105 	}
106 
107 	return io;
108 }
109 
io_openfd(int fd)110 struct io * io_openfd(int fd)
111 {
112 	struct io *io = io_new();
113 	int ret;
114 
115 	if (!io)
116 		return NULL;
117 
118 	ret = archive_read_open_fd(io->a, fd, 10240);
119 	if (ret != ARCHIVE_OK) {
120 		io_error(io);
121 		return NULL;
122 	}
123 
124 	ret = archive_read_next_header(io->a, &io->entry);
125 	if (ret != ARCHIVE_OK) {
126 		io_error(io);
127 		return NULL;
128 	}
129 
130 	return io;
131 }
132 
io_close(struct io * io)133 void io_close(struct io *io)
134 {
135 	archive_read_free(io->a);
136 	free(io);
137 }
138 
io_offset(struct io * io)139 unsigned io_offset(struct io *io)
140 {
141 	return io->offset;
142 }
143 
144 #include <assert.h>
io_readn(struct io * io,void * buf,int nbytes)145 int io_readn(struct io *io, void *buf, int nbytes)
146 {
147 	char *ptr = buf;
148 	int ret = 0;
149 	while (nbytes > 0) {
150 		int n = archive_read_data(io->a, ptr, nbytes);
151 		if (n < 0) {
152 			fprintf(stderr, "%s\n", archive_error_string(io->a));
153 			return n;
154 		}
155 		if (n == 0)
156 			break;
157 		ptr += n;
158 		nbytes -= n;
159 		ret += n;
160 		io->offset += n;
161 	}
162 	return ret;
163 }
164