|
rhughes@241
|
1 |
/*
|
|
rhughes@241
|
2 |
* Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
|
|
rhughes@241
|
3 |
* Copyright (C) 2008 Red Hat, Inc
|
|
rhughes@241
|
4 |
*
|
|
rhughes@241
|
5 |
* This program is free software; you can redistribute it and/or modify
|
|
rhughes@241
|
6 |
* it under the terms of the GNU General Public License as published by
|
|
rhughes@241
|
7 |
* the Free Software Foundation; either version 2 of the License, or
|
|
rhughes@241
|
8 |
* (at your option) any later version.
|
|
rhughes@241
|
9 |
*
|
|
rhughes@241
|
10 |
* This program is distributed in the hope that it will be useful,
|
|
rhughes@241
|
11 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
rhughes@241
|
12 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
rhughes@241
|
13 |
* GNU General Public License for more details.
|
|
rhughes@241
|
14 |
*
|
|
rhughes@241
|
15 |
* You should have received a copy of the GNU General Public License along
|
|
rhughes@241
|
16 |
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
rhughes@241
|
17 |
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
rhughes@241
|
18 |
*/
|
|
rhughes@241
|
19 |
|
|
rhughes@241
|
20 |
#define _GNU_SOURCE
|
|
rhughes@241
|
21 |
|
|
rhughes@241
|
22 |
#include <stdlib.h>
|
|
rhughes@241
|
23 |
#include <stddef.h>
|
|
rhughes@241
|
24 |
#include <stdint.h>
|
|
rhughes@241
|
25 |
#include <stdio.h>
|
|
rhughes@241
|
26 |
#include <string.h>
|
|
rhughes@241
|
27 |
#include <sys/types.h>
|
|
rhughes@241
|
28 |
#include <sys/stat.h>
|
|
rhughes@241
|
29 |
#include <sys/mman.h>
|
|
rhughes@241
|
30 |
#include <unistd.h>
|
|
rhughes@241
|
31 |
#include <fcntl.h>
|
|
rhughes@241
|
32 |
#include <errno.h>
|
|
rhughes@241
|
33 |
#include <ctype.h>
|
|
rhughes@241
|
34 |
#include <fnmatch.h>
|
|
rhughes@241
|
35 |
|
|
krh@253
|
36 |
#include "razor-internal.h"
|
|
rhughes@241
|
37 |
#include "razor.h"
|
|
rhughes@241
|
38 |
|
|
krh@248
|
39 |
void *
|
|
rhughes@241
|
40 |
zalloc(size_t size)
|
|
rhughes@241
|
41 |
{
|
|
rhughes@241
|
42 |
void *p;
|
|
rhughes@241
|
43 |
|
|
rhughes@241
|
44 |
p = malloc(size);
|
|
rhughes@241
|
45 |
memset(p, 0, size);
|
|
rhughes@241
|
46 |
|
|
rhughes@241
|
47 |
return p;
|
|
rhughes@241
|
48 |
}
|
|
rhughes@241
|
49 |
|
|
rhughes@241
|
50 |
struct razor_set_section razor_sections[] = {
|
|
rhughes@241
|
51 |
{ RAZOR_STRING_POOL, offsetof(struct razor_set, string_pool) },
|
|
rhughes@241
|
52 |
{ RAZOR_PACKAGES, offsetof(struct razor_set, packages) },
|
|
rhughes@241
|
53 |
{ RAZOR_PROPERTIES, offsetof(struct razor_set, properties) },
|
|
rhughes@241
|
54 |
{ RAZOR_PACKAGE_POOL, offsetof(struct razor_set, package_pool) },
|
|
rhughes@241
|
55 |
{ RAZOR_PROPERTY_POOL, offsetof(struct razor_set, property_pool) },
|
|
rhughes@241
|
56 |
};
|
|
rhughes@241
|
57 |
|
|
jbowes@258
|
58 |
struct razor_set_section razor_files_sections[] = {
|
|
jbowes@258
|
59 |
{ RAZOR_FILES, offsetof(struct razor_set, files) },
|
|
jbowes@258
|
60 |
{ RAZOR_FILE_POOL, offsetof(struct razor_set, file_pool) },
|
|
jbowes@258
|
61 |
{ RAZOR_FILE_STRING_POOL, offsetof(struct razor_set, file_string_pool) },
|
|
jbowes@258
|
62 |
};
|
|
jbowes@258
|
63 |
|
|
jbowes@258
|
64 |
struct razor_set_section razor_details_sections[] = {
|
|
jbowes@258
|
65 |
{ RAZOR_DETAILS_STRING_POOL, offsetof(struct razor_set, details_string_pool) },
|
|
jbowes@258
|
66 |
};
|
|
rhughes@241
|
67 |
struct razor_set *
|
|
rhughes@241
|
68 |
razor_set_create(void)
|
|
rhughes@241
|
69 |
{
|
|
rhughes@241
|
70 |
struct razor_set *set;
|
|
rhughes@241
|
71 |
struct razor_entry *e;
|
|
rhughes@241
|
72 |
char *empty;
|
|
rhughes@241
|
73 |
|
|
rhughes@241
|
74 |
set = zalloc(sizeof *set);
|
|
rhughes@241
|
75 |
|
|
rhughes@241
|
76 |
e = array_add(&set->files, sizeof *e);
|
|
rhughes@241
|
77 |
empty = array_add(&set->string_pool, 1);
|
|
rhughes@241
|
78 |
*empty = '\0';
|
|
rhughes@241
|
79 |
e->name = 0;
|
|
rhughes@241
|
80 |
e->flags = RAZOR_ENTRY_LAST;
|
|
rhughes@241
|
81 |
e->start = 0;
|
|
rhughes@241
|
82 |
list_set_empty(&e->packages);
|
|
rhughes@241
|
83 |
|
|
rhughes@241
|
84 |
return set;
|
|
rhughes@241
|
85 |
}
|
|
rhughes@241
|
86 |
|
|
rhughes@241
|
87 |
struct razor_set *
|
|
rhughes@241
|
88 |
razor_set_open(const char *filename)
|
|
rhughes@241
|
89 |
{
|
|
rhughes@241
|
90 |
struct razor_set *set;
|
|
rhughes@241
|
91 |
struct razor_set_section *s;
|
|
rhughes@241
|
92 |
struct stat stat;
|
|
rhughes@241
|
93 |
struct array *array;
|
|
rhughes@241
|
94 |
int fd;
|
|
rhughes@241
|
95 |
|
|
rhughes@241
|
96 |
set = zalloc(sizeof *set);
|
|
rhughes@241
|
97 |
fd = open(filename, O_RDONLY);
|
|
rhughes@241
|
98 |
if (fstat(fd, &stat) < 0)
|
|
rhughes@241
|
99 |
return NULL;
|
|
rhughes@241
|
100 |
set->header = mmap(NULL, stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
|
|
rhughes@241
|
101 |
if (set->header == MAP_FAILED) {
|
|
rhughes@241
|
102 |
free(set);
|
|
rhughes@241
|
103 |
return NULL;
|
|
rhughes@241
|
104 |
}
|
|
rhughes@241
|
105 |
|
|
rhughes@241
|
106 |
for (s = set->header->sections; ~s->type; s++) {
|
|
rhughes@241
|
107 |
if (s->type >= ARRAY_SIZE(razor_sections))
|
|
rhughes@241
|
108 |
continue;
|
|
rhughes@241
|
109 |
if (s->type != razor_sections[s->type].type)
|
|
rhughes@241
|
110 |
continue;
|
|
rhughes@241
|
111 |
array = (void *) set + razor_sections[s->type].offset;
|
|
rhughes@241
|
112 |
array->data = (void *) set->header + s->offset;
|
|
rhughes@241
|
113 |
array->size = s->size;
|
|
rhughes@241
|
114 |
array->alloc = s->size;
|
|
rhughes@241
|
115 |
}
|
|
rhughes@241
|
116 |
close(fd);
|
|
rhughes@241
|
117 |
|
|
rhughes@241
|
118 |
return set;
|
|
rhughes@241
|
119 |
}
|
|
rhughes@241
|
120 |
|
|
rhughes@241
|
121 |
void
|
|
jbowes@258
|
122 |
razor_set_open_details(struct razor_set *set, const char *filename)
|
|
jbowes@258
|
123 |
{
|
|
jbowes@258
|
124 |
struct razor_set_section *s;
|
|
jbowes@258
|
125 |
struct stat stat;
|
|
jbowes@258
|
126 |
struct array *array;
|
|
jbowes@258
|
127 |
int fd;
|
|
jbowes@258
|
128 |
|
|
jbowes@258
|
129 |
fd = open(filename, O_RDONLY);
|
|
jbowes@258
|
130 |
if (fstat(fd, &stat) < 0)
|
|
jbowes@258
|
131 |
return;
|
|
jbowes@258
|
132 |
set->details_header = mmap(NULL, stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
|
|
jbowes@258
|
133 |
if (set->details_header == MAP_FAILED)
|
|
jbowes@258
|
134 |
return;
|
|
jbowes@258
|
135 |
|
|
jbowes@258
|
136 |
for (s = set->details_header->sections; ~s->type; s++) {
|
|
jbowes@258
|
137 |
if (s->type >= ARRAY_SIZE(razor_details_sections))
|
|
jbowes@258
|
138 |
continue;
|
|
jbowes@258
|
139 |
if (s->type != razor_details_sections[s->type].type)
|
|
jbowes@258
|
140 |
continue;
|
|
jbowes@258
|
141 |
array = (void *) set + razor_details_sections[s->type].offset;
|
|
jbowes@258
|
142 |
array->data = (void *) set->details_header + s->offset;
|
|
jbowes@258
|
143 |
array->size = s->size;
|
|
jbowes@258
|
144 |
array->alloc = s->size;
|
|
jbowes@258
|
145 |
}
|
|
jbowes@258
|
146 |
close(fd);
|
|
jbowes@258
|
147 |
}
|
|
jbowes@258
|
148 |
|
|
jbowes@258
|
149 |
void
|
|
jbowes@258
|
150 |
razor_set_open_files(struct razor_set *set, const char *filename)
|
|
jbowes@258
|
151 |
{
|
|
jbowes@258
|
152 |
struct razor_set_section *s;
|
|
jbowes@258
|
153 |
struct stat stat;
|
|
jbowes@258
|
154 |
struct array *array;
|
|
jbowes@258
|
155 |
int fd;
|
|
jbowes@258
|
156 |
|
|
jbowes@258
|
157 |
fd = open(filename, O_RDONLY);
|
|
jbowes@258
|
158 |
if (fstat(fd, &stat) < 0)
|
|
jbowes@258
|
159 |
return;
|
|
jbowes@258
|
160 |
set->files_header = mmap(NULL, stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
|
|
jbowes@258
|
161 |
if (set->files_header == MAP_FAILED)
|
|
jbowes@258
|
162 |
return;
|
|
jbowes@258
|
163 |
|
|
jbowes@258
|
164 |
for (s = set->files_header->sections; ~s->type; s++) {
|
|
jbowes@258
|
165 |
if (s->type >= ARRAY_SIZE(razor_files_sections))
|
|
jbowes@258
|
166 |
continue;
|
|
jbowes@258
|
167 |
if (s->type != razor_files_sections[s->type].type)
|
|
jbowes@258
|
168 |
continue;
|
|
jbowes@258
|
169 |
array = (void *) set + razor_files_sections[s->type].offset;
|
|
jbowes@258
|
170 |
array->data = (void *) set->files_header + s->offset;
|
|
jbowes@258
|
171 |
array->size = s->size;
|
|
jbowes@258
|
172 |
array->alloc = s->size;
|
|
jbowes@258
|
173 |
}
|
|
jbowes@258
|
174 |
close(fd);
|
|
jbowes@258
|
175 |
}
|
|
jbowes@258
|
176 |
|
|
jbowes@258
|
177 |
void
|
|
rhughes@241
|
178 |
razor_set_destroy(struct razor_set *set)
|
|
rhughes@241
|
179 |
{
|
|
rhughes@241
|
180 |
unsigned int size;
|
|
rhughes@241
|
181 |
struct array *a;
|
|
rhughes@241
|
182 |
int i;
|
|
rhughes@241
|
183 |
|
|
rhughes@241
|
184 |
if (set->header) {
|
|
rhughes@241
|
185 |
for (i = 0; set->header->sections[i].type; i++)
|
|
rhughes@241
|
186 |
;
|
|
rhughes@241
|
187 |
size = set->header->sections[i].type;
|
|
rhughes@241
|
188 |
munmap(set->header, size);
|
|
rhughes@241
|
189 |
} else {
|
|
rhughes@241
|
190 |
for (i = 0; i < ARRAY_SIZE(razor_sections); i++) {
|
|
rhughes@241
|
191 |
a = (void *) set + razor_sections[i].offset;
|
|
rhughes@241
|
192 |
free(a->data);
|
|
rhughes@241
|
193 |
}
|
|
rhughes@241
|
194 |
}
|
|
rhughes@241
|
195 |
|
|
jbowes@258
|
196 |
if (set->details_header) {
|
|
jbowes@258
|
197 |
for (i = 0; set->details_header->sections[i].type; i++)
|
|
jbowes@258
|
198 |
;
|
|
jbowes@258
|
199 |
size = set->details_header->sections[i].type;
|
|
jbowes@258
|
200 |
munmap(set->details_header, size);
|
|
jbowes@258
|
201 |
} else {
|
|
jbowes@258
|
202 |
for (i = 0; i < ARRAY_SIZE(razor_details_sections); i++) {
|
|
jbowes@258
|
203 |
a = (void *) set + razor_details_sections[i].offset;
|
|
jbowes@258
|
204 |
free(a->data);
|
|
jbowes@258
|
205 |
}
|
|
jbowes@258
|
206 |
}
|
|
jbowes@258
|
207 |
|
|
jbowes@258
|
208 |
if (set->files_header) {
|
|
jbowes@258
|
209 |
for (i = 0; set->files_header->sections[i].type; i++)
|
|
jbowes@258
|
210 |
;
|
|
jbowes@258
|
211 |
size = set->files_header->sections[i].type;
|
|
jbowes@258
|
212 |
munmap(set->files_header, size);
|
|
jbowes@258
|
213 |
} else {
|
|
jbowes@258
|
214 |
for (i = 0; i < ARRAY_SIZE(razor_files_sections); i++) {
|
|
jbowes@258
|
215 |
a = (void *) set + razor_files_sections[i].offset;
|
|
jbowes@258
|
216 |
free(a->data);
|
|
jbowes@258
|
217 |
}
|
|
jbowes@258
|
218 |
}
|
|
jbowes@258
|
219 |
|
|
rhughes@241
|
220 |
free(set);
|
|
rhughes@241
|
221 |
}
|
|
rhughes@241
|
222 |
|
|
jbowes@258
|
223 |
static int
|
|
jbowes@258
|
224 |
razor_set_write_sections_to_fd(struct razor_set *set, int fd, int magic,
|
|
jbowes@258
|
225 |
struct razor_set_section *sections,
|
|
jbowes@258
|
226 |
size_t array_size)
|
|
rhughes@241
|
227 |
{
|
|
rhughes@241
|
228 |
char data[4096];
|
|
rhughes@241
|
229 |
struct razor_set_header *header = (struct razor_set_header *) data;
|
|
rhughes@241
|
230 |
struct array *a;
|
|
rhughes@241
|
231 |
uint32_t offset;
|
|
rhughes@241
|
232 |
int i;
|
|
rhughes@241
|
233 |
|
|
rhughes@241
|
234 |
memset(data, 0, sizeof data);
|
|
jbowes@258
|
235 |
header->magic = magic;
|
|
rhughes@241
|
236 |
header->version = RAZOR_VERSION;
|
|
rhughes@241
|
237 |
offset = sizeof data;
|
|
rhughes@241
|
238 |
|
|
jbowes@258
|
239 |
for (i = 0; i < array_size; i++) {
|
|
jbowes@258
|
240 |
if (sections[i].type != i)
|
|
rhughes@241
|
241 |
continue;
|
|
jbowes@258
|
242 |
a = (void *) set + sections[i].offset;
|
|
rhughes@241
|
243 |
header->sections[i].type = i;
|
|
rhughes@241
|
244 |
header->sections[i].offset = offset;
|
|
rhughes@241
|
245 |
header->sections[i].size = a->size;
|
|
rhughes@241
|
246 |
offset += ALIGN(a->size, 4096);
|
|
rhughes@241
|
247 |
}
|
|
rhughes@241
|
248 |
|
|
rhughes@241
|
249 |
header->sections[i].type = ~0;
|
|
rhughes@241
|
250 |
header->sections[i].offset = 0;
|
|
rhughes@241
|
251 |
header->sections[i].size = 0;
|
|
rhughes@241
|
252 |
|
|
rhughes@241
|
253 |
razor_write(fd, data, sizeof data);
|
|
rhughes@241
|
254 |
memset(data, 0, sizeof data);
|
|
jbowes@258
|
255 |
for (i = 0; i < array_size; i++) {
|
|
jbowes@258
|
256 |
if (sections[i].type != i)
|
|
rhughes@241
|
257 |
continue;
|
|
jbowes@258
|
258 |
a = (void *) set + sections[i].offset;
|
|
rhughes@241
|
259 |
razor_write(fd, a->data, a->size);
|
|
rhughes@241
|
260 |
razor_write(fd, data, ALIGN(a->size, 4096) - a->size);
|
|
rhughes@241
|
261 |
}
|
|
rhughes@241
|
262 |
|
|
rhughes@241
|
263 |
return 0;
|
|
rhughes@241
|
264 |
}
|
|
rhughes@241
|
265 |
|
|
rhughes@241
|
266 |
int
|
|
jbowes@258
|
267 |
razor_set_write_to_fd(struct razor_set *set, int fd,
|
|
jbowes@258
|
268 |
enum razor_repo_file_type type)
|
|
jbowes@258
|
269 |
{
|
|
jbowes@258
|
270 |
switch (type) {
|
|
jbowes@258
|
271 |
case RAZOR_REPO_FILE_MAIN:
|
|
jbowes@258
|
272 |
return razor_set_write_sections_to_fd(set, fd, RAZOR_MAGIC,
|
|
jbowes@258
|
273 |
razor_sections,
|
|
jbowes@258
|
274 |
ARRAY_SIZE(razor_sections));
|
|
jbowes@258
|
275 |
|
|
jbowes@258
|
276 |
case RAZOR_REPO_FILE_DETAILS:
|
|
jbowes@258
|
277 |
return razor_set_write_sections_to_fd(set, fd, RAZOR_DETAILS_MAGIC,
|
|
jbowes@258
|
278 |
razor_details_sections,
|
|
jbowes@258
|
279 |
ARRAY_SIZE(razor_details_sections));
|
|
jbowes@258
|
280 |
case RAZOR_REPO_FILE_FILES:
|
|
jbowes@258
|
281 |
return razor_set_write_sections_to_fd(set, fd, RAZOR_FILES_MAGIC,
|
|
jbowes@258
|
282 |
razor_files_sections,
|
|
jbowes@258
|
283 |
ARRAY_SIZE(razor_files_sections));
|
|
jbowes@258
|
284 |
default:
|
|
jbowes@258
|
285 |
return -1;
|
|
jbowes@258
|
286 |
}
|
|
jbowes@258
|
287 |
}
|
|
jbowes@258
|
288 |
|
|
jbowes@258
|
289 |
int
|
|
jbowes@258
|
290 |
razor_set_write(struct razor_set *set, const char *filename,
|
|
jbowes@258
|
291 |
enum razor_repo_file_type type)
|
|
rhughes@241
|
292 |
{
|
|
rhughes@241
|
293 |
int fd, status;
|
|
rhughes@241
|
294 |
|
|
rhughes@241
|
295 |
fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0666);
|
|
rhughes@241
|
296 |
if (fd < 0)
|
|
rhughes@241
|
297 |
return -1;
|
|
rhughes@241
|
298 |
|
|
jbowes@258
|
299 |
status = razor_set_write_to_fd(set, fd, type);
|
|
rhughes@241
|
300 |
if (status) {
|
|
rhughes@241
|
301 |
close(fd);
|
|
rhughes@241
|
302 |
return status;
|
|
rhughes@241
|
303 |
}
|
|
rhughes@241
|
304 |
|
|
rhughes@241
|
305 |
return close(fd);
|
|
rhughes@241
|
306 |
}
|
|
rhughes@241
|
307 |
void
|
|
rhughes@241
|
308 |
razor_build_evr(char *evr_buf, int size, const char *epoch,
|
|
rhughes@241
|
309 |
const char *version, const char *release)
|
|
rhughes@241
|
310 |
{
|
|
rhughes@241
|
311 |
int len;
|
|
rhughes@241
|
312 |
|
|
rhughes@241
|
313 |
if (!version || !*version) {
|
|
rhughes@241
|
314 |
*evr_buf = '\0';
|
|
rhughes@241
|
315 |
return;
|
|
rhughes@241
|
316 |
}
|
|
rhughes@241
|
317 |
|
|
rhughes@241
|
318 |
if (epoch && *epoch && strcmp(epoch, "0") != 0) {
|
|
rhughes@241
|
319 |
len = snprintf(evr_buf, size, "%s:", epoch);
|
|
rhughes@241
|
320 |
evr_buf += len;
|
|
rhughes@241
|
321 |
size -= len;
|
|
rhughes@241
|
322 |
}
|
|
rhughes@241
|
323 |
len = snprintf(evr_buf, size, "%s", version);
|
|
rhughes@241
|
324 |
evr_buf += len;
|
|
rhughes@241
|
325 |
size -= len;
|
|
rhughes@241
|
326 |
if (release && *release)
|
|
rhughes@241
|
327 |
snprintf(evr_buf, size, "-%s", release);
|
|
rhughes@241
|
328 |
}
|
|
rhughes@241
|
329 |
|
|
krh@248
|
330 |
int
|
|
krh@248
|
331 |
razor_versioncmp(const char *s1, const char *s2)
|
|
rhughes@241
|
332 |
{
|
|
rhughes@241
|
333 |
const char *p1, *p2;
|
|
rhughes@241
|
334 |
long n1, n2;
|
|
rhughes@241
|
335 |
int res;
|
|
rhughes@241
|
336 |
|
|
rhughes@241
|
337 |
n1 = strtol(s1, (char **) &p1, 10);
|
|
rhughes@241
|
338 |
n2 = strtol(s2, (char **) &p2, 10);
|
|
rhughes@241
|
339 |
|
|
rhughes@241
|
340 |
/* Epoch; if one but not the other has an epoch set, default
|
|
rhughes@241
|
341 |
* the epoch-less version to 0. */
|
|
rhughes@241
|
342 |
res = (*p1 == ':') - (*p2 == ':');
|
|
rhughes@241
|
343 |
if (res < 0) {
|
|
rhughes@241
|
344 |
n1 = 0;
|
|
rhughes@241
|
345 |
p1 = s1;
|
|
rhughes@241
|
346 |
p2++;
|
|
rhughes@241
|
347 |
} else if (res > 0) {
|
|
rhughes@241
|
348 |
p1++;
|
|
rhughes@241
|
349 |
n2 = 0;
|
|
rhughes@241
|
350 |
p2 = s2;
|
|
rhughes@241
|
351 |
}
|
|
rhughes@241
|
352 |
|
|
rhughes@241
|
353 |
if (n1 != n2)
|
|
rhughes@241
|
354 |
return n1 - n2;
|
|
rhughes@241
|
355 |
while (*p1 && *p2) {
|
|
rhughes@241
|
356 |
if (*p1 != *p2)
|
|
rhughes@241
|
357 |
return *p1 - *p2;
|
|
rhughes@241
|
358 |
p1++;
|
|
rhughes@241
|
359 |
p2++;
|
|
rhughes@241
|
360 |
if (isdigit(*p1) && isdigit(*p2))
|
|
krh@248
|
361 |
return razor_versioncmp(p1, p2);
|
|
rhughes@241
|
362 |
}
|
|
rhughes@241
|
363 |
|
|
rhughes@241
|
364 |
return *p1 - *p2;
|
|
rhughes@241
|
365 |
}
|
|
rhughes@241
|
366 |
|
|
rhughes@241
|
367 |
struct razor_package *
|
|
rhughes@241
|
368 |
razor_set_get_package(struct razor_set *set, const char *package)
|
|
rhughes@241
|
369 |
{
|
|
rhughes@241
|
370 |
struct razor_package_iterator *pi;
|
|
rhughes@241
|
371 |
struct razor_package *p;
|
|
rhughes@241
|
372 |
const char *name, *version, *arch;
|
|
rhughes@241
|
373 |
|
|
rhughes@241
|
374 |
pi = razor_package_iterator_create(set);
|
|
rhughes@241
|
375 |
while (razor_package_iterator_next(pi, &p, &name, &version, &arch)) {
|
|
rhughes@241
|
376 |
if (strcmp(package, name) == 0)
|
|
rhughes@241
|
377 |
break;
|
|
rhughes@241
|
378 |
}
|
|
rhughes@241
|
379 |
razor_package_iterator_destroy(pi);
|
|
rhughes@241
|
380 |
|
|
rhughes@241
|
381 |
return p;
|
|
rhughes@241
|
382 |
}
|
|
rhughes@241
|
383 |
|
|
jbowes@258
|
384 |
void
|
|
jbowes@258
|
385 |
razor_package_get_details(struct razor_set *set, struct razor_package *package,
|
|
jbowes@258
|
386 |
const char **summary, const char **description,
|
|
jbowes@258
|
387 |
const char **url, const char **license)
|
|
jbowes@258
|
388 |
{
|
|
jbowes@258
|
389 |
const char *pool = set->details_string_pool.data;
|
|
jbowes@258
|
390 |
|
|
jbowes@258
|
391 |
*summary = &pool[package->summary];
|
|
jbowes@258
|
392 |
*description = &pool[package->description];
|
|
jbowes@258
|
393 |
*url = &pool[package->url];
|
|
jbowes@258
|
394 |
*license = &pool[package->license];
|
|
jbowes@258
|
395 |
}
|
|
jbowes@258
|
396 |
|
|
krh@248
|
397 |
struct razor_entry *
|
|
krh@248
|
398 |
razor_set_find_entry(struct razor_set *set,
|
|
krh@248
|
399 |
struct razor_entry *dir, const char *pattern)
|
|
rhughes@241
|
400 |
{
|
|
rhughes@241
|
401 |
struct razor_entry *e;
|
|
rhughes@241
|
402 |
const char *n, *pool = set->string_pool.data;
|
|
rhughes@241
|
403 |
int len;
|
|
rhughes@241
|
404 |
|
|
rhughes@241
|
405 |
e = (struct razor_entry *) set->files.data + dir->start;
|
|
rhughes@241
|
406 |
do {
|
|
rhughes@241
|
407 |
n = pool + e->name;
|
|
rhughes@241
|
408 |
if (strcmp(pattern + 1, n) == 0)
|
|
rhughes@241
|
409 |
return e;
|
|
rhughes@241
|
410 |
len = strlen(n);
|
|
rhughes@241
|
411 |
if (e->start != 0 && strncmp(pattern + 1, n, len) == 0 &&
|
|
rhughes@241
|
412 |
pattern[len + 1] == '/') {
|
|
krh@248
|
413 |
return razor_set_find_entry(set, e, pattern + len + 1);
|
|
rhughes@241
|
414 |
}
|
|
rhughes@241
|
415 |
} while (!((e++)->flags & RAZOR_ENTRY_LAST));
|
|
rhughes@241
|
416 |
|
|
rhughes@241
|
417 |
return NULL;
|
|
rhughes@241
|
418 |
}
|
|
rhughes@241
|
419 |
|
|
rhughes@241
|
420 |
static void
|
|
rhughes@241
|
421 |
list_dir(struct razor_set *set, struct razor_entry *dir,
|
|
rhughes@241
|
422 |
char *prefix, const char *pattern)
|
|
rhughes@241
|
423 |
{
|
|
rhughes@241
|
424 |
struct razor_entry *e;
|
|
rhughes@241
|
425 |
const char *n, *pool = set->string_pool.data;
|
|
rhughes@241
|
426 |
|
|
rhughes@241
|
427 |
e = (struct razor_entry *) set->files.data + dir->start;
|
|
rhughes@241
|
428 |
do {
|
|
rhughes@241
|
429 |
n = pool + e->name;
|
|
rhughes@241
|
430 |
if (pattern && pattern[0] && fnmatch(pattern, n, 0) != 0)
|
|
rhughes@241
|
431 |
continue;
|
|
rhughes@241
|
432 |
printf("%s/%s\n", prefix, n);
|
|
rhughes@241
|
433 |
if (e->start) {
|
|
rhughes@241
|
434 |
char *sub = prefix + strlen (prefix);
|
|
rhughes@241
|
435 |
*sub = '/';
|
|
rhughes@241
|
436 |
strcpy (sub + 1, n);
|
|
rhughes@241
|
437 |
list_dir(set, e, prefix, pattern);
|
|
rhughes@241
|
438 |
*sub = '\0';
|
|
rhughes@241
|
439 |
}
|
|
rhughes@241
|
440 |
} while (!((e++)->flags & RAZOR_ENTRY_LAST));
|
|
rhughes@241
|
441 |
}
|
|
rhughes@241
|
442 |
|
|
rhughes@241
|
443 |
void
|
|
rhughes@241
|
444 |
razor_set_list_files(struct razor_set *set, const char *pattern)
|
|
rhughes@241
|
445 |
{
|
|
rhughes@241
|
446 |
struct razor_entry *e;
|
|
rhughes@241
|
447 |
char buffer[512], *p, *base;
|
|
rhughes@241
|
448 |
|
|
rhughes@241
|
449 |
if (pattern == NULL || !strcmp (pattern, "/")) {
|
|
rhughes@241
|
450 |
buffer[0] = '\0';
|
|
rhughes@241
|
451 |
list_dir(set, set->files.data, buffer, NULL);
|
|
rhughes@241
|
452 |
return;
|
|
rhughes@241
|
453 |
}
|
|
rhughes@241
|
454 |
|
|
rhughes@241
|
455 |
strcpy(buffer, pattern);
|
|
krh@248
|
456 |
e = razor_set_find_entry(set, set->files.data, buffer);
|
|
rhughes@241
|
457 |
if (e && e->start > 0) {
|
|
rhughes@241
|
458 |
base = NULL;
|
|
rhughes@241
|
459 |
} else {
|
|
rhughes@241
|
460 |
p = strrchr(buffer, '/');
|
|
rhughes@241
|
461 |
if (p) {
|
|
rhughes@241
|
462 |
*p = '\0';
|
|
rhughes@241
|
463 |
base = p + 1;
|
|
rhughes@241
|
464 |
} else {
|
|
rhughes@241
|
465 |
base = NULL;
|
|
rhughes@241
|
466 |
}
|
|
rhughes@241
|
467 |
}
|
|
krh@248
|
468 |
e = razor_set_find_entry(set, set->files.data, buffer);
|
|
rhughes@241
|
469 |
if (e->start != 0)
|
|
rhughes@241
|
470 |
list_dir(set, e, buffer, base);
|
|
rhughes@241
|
471 |
}
|
|
rhughes@241
|
472 |
|
|
rhughes@241
|
473 |
static struct list *
|
|
rhughes@241
|
474 |
list_package_files(struct razor_set *set, struct list *r,
|
|
rhughes@241
|
475 |
struct razor_entry *dir, uint32_t end,
|
|
rhughes@241
|
476 |
char *prefix)
|
|
rhughes@241
|
477 |
{
|
|
rhughes@241
|
478 |
struct razor_entry *e, *f, *entries;
|
|
rhughes@241
|
479 |
uint32_t next, file;
|
|
rhughes@241
|
480 |
char *pool;
|
|
rhughes@241
|
481 |
int len;
|
|
rhughes@241
|
482 |
|
|
rhughes@241
|
483 |
entries = (struct razor_entry *) set->files.data;
|
|
rhughes@241
|
484 |
pool = set->string_pool.data;
|
|
rhughes@241
|
485 |
|
|
rhughes@241
|
486 |
e = entries + dir->start;
|
|
rhughes@241
|
487 |
do {
|
|
rhughes@241
|
488 |
if (entries + r->data == e) {
|
|
rhughes@241
|
489 |
printf("%s/%s\n", prefix, pool + e->name);
|
|
rhughes@241
|
490 |
r = list_next(r);
|
|
rhughes@241
|
491 |
if (!r)
|
|
rhughes@241
|
492 |
return NULL;
|
|
rhughes@241
|
493 |
if (r->data >= end)
|
|
rhughes@241
|
494 |
return r;
|
|
rhughes@241
|
495 |
}
|
|
rhughes@241
|
496 |
} while (!((e++)->flags & RAZOR_ENTRY_LAST));
|
|
rhughes@241
|
497 |
|
|
rhughes@241
|
498 |
e = entries + dir->start;
|
|
rhughes@241
|
499 |
do {
|
|
rhughes@241
|
500 |
if (e->start == 0)
|
|
rhughes@241
|
501 |
continue;
|
|
rhughes@241
|
502 |
|
|
rhughes@241
|
503 |
if (e->flags & RAZOR_ENTRY_LAST)
|
|
rhughes@241
|
504 |
next = end;
|
|
rhughes@241
|
505 |
else {
|
|
rhughes@241
|
506 |
f = e + 1;
|
|
rhughes@241
|
507 |
while (f->start == 0 && !(f->flags & RAZOR_ENTRY_LAST))
|
|
rhughes@241
|
508 |
f++;
|
|
rhughes@241
|
509 |
if (f->start == 0)
|
|
rhughes@241
|
510 |
next = end;
|
|
rhughes@241
|
511 |
else
|
|
rhughes@241
|
512 |
next = f->start;
|
|
rhughes@241
|
513 |
}
|
|
rhughes@241
|
514 |
|
|
rhughes@241
|
515 |
file = r->data;
|
|
rhughes@241
|
516 |
if (e->start <= file && file < next) {
|
|
rhughes@241
|
517 |
len = strlen(prefix);
|
|
rhughes@241
|
518 |
prefix[len] = '/';
|
|
rhughes@241
|
519 |
strcpy(prefix + len + 1, pool + e->name);
|
|
rhughes@241
|
520 |
r = list_package_files(set, r, e, next, prefix);
|
|
rhughes@241
|
521 |
prefix[len] = '\0';
|
|
rhughes@241
|
522 |
}
|
|
rhughes@241
|
523 |
} while (!((e++)->flags & RAZOR_ENTRY_LAST) && r != NULL);
|
|
rhughes@241
|
524 |
|
|
rhughes@241
|
525 |
return r;
|
|
rhughes@241
|
526 |
}
|
|
rhughes@241
|
527 |
|
|
rhughes@241
|
528 |
void
|
|
rhughes@241
|
529 |
razor_set_list_package_files(struct razor_set *set, const char *name)
|
|
rhughes@241
|
530 |
{
|
|
rhughes@241
|
531 |
struct razor_package *package;
|
|
rhughes@241
|
532 |
struct list *r;
|
|
rhughes@241
|
533 |
uint32_t end;
|
|
rhughes@241
|
534 |
char buffer[512];
|
|
rhughes@241
|
535 |
|
|
rhughes@241
|
536 |
package = razor_set_get_package(set, name);
|
|
rhughes@241
|
537 |
|
|
rhughes@241
|
538 |
r = list_first(&package->files, &set->file_pool);
|
|
rhughes@241
|
539 |
end = set->files.size / sizeof (struct razor_entry);
|
|
rhughes@241
|
540 |
buffer[0] = '\0';
|
|
rhughes@241
|
541 |
list_package_files(set, r, set->files.data, end, buffer);
|
|
rhughes@241
|
542 |
}
|
|
rhughes@241
|
543 |
|
|
rhughes@241
|
544 |
/* The diff order matters. We should sort the packages so that a
|
|
rhughes@241
|
545 |
* REMOVE of a package comes before the INSTALL, and so that all
|
|
rhughes@241
|
546 |
* requires for a package have been installed before the package.
|
|
rhughes@241
|
547 |
**/
|
|
rhughes@241
|
548 |
|
|
rhughes@241
|
549 |
void
|
|
rhughes@241
|
550 |
razor_set_diff(struct razor_set *set, struct razor_set *upstream,
|
|
krh@253
|
551 |
razor_diff_callback_t callback, void *data)
|
|
rhughes@241
|
552 |
{
|
|
rhughes@241
|
553 |
struct razor_package_iterator *pi1, *pi2;
|
|
rhughes@241
|
554 |
struct razor_package *p1, *p2;
|
|
rhughes@241
|
555 |
const char *name1, *name2, *version1, *version2, *arch1, *arch2;
|
|
rhughes@241
|
556 |
int res;
|
|
rhughes@241
|
557 |
|
|
rhughes@241
|
558 |
pi1 = razor_package_iterator_create(set);
|
|
rhughes@241
|
559 |
pi2 = razor_package_iterator_create(upstream);
|
|
rhughes@241
|
560 |
|
|
rhughes@241
|
561 |
razor_package_iterator_next(pi1, &p1, &name1, &version1, &arch1);
|
|
rhughes@241
|
562 |
razor_package_iterator_next(pi2, &p2, &name2, &version2, &arch2);
|
|
rhughes@241
|
563 |
|
|
rhughes@241
|
564 |
while (p1 || p2) {
|
|
rhughes@241
|
565 |
if (p1 && p2) {
|
|
rhughes@241
|
566 |
res = strcmp(name1, name2);
|
|
rhughes@241
|
567 |
if (res == 0)
|
|
krh@248
|
568 |
res = razor_versioncmp(version1, version2);
|
|
rhughes@241
|
569 |
} else {
|
|
rhughes@241
|
570 |
res = 0;
|
|
rhughes@241
|
571 |
}
|
|
rhughes@241
|
572 |
|
|
rhughes@241
|
573 |
if (p2 == NULL || res < 0)
|
|
krh@253
|
574 |
callback(RAZOR_DIFF_ACTION_REMOVE,
|
|
krh@253
|
575 |
p1, name1, version1, arch1, data);
|
|
rhughes@241
|
576 |
else if (p1 == NULL || res > 0)
|
|
krh@253
|
577 |
callback(RAZOR_DIFF_ACTION_ADD,
|
|
krh@253
|
578 |
p2, name2, version2, arch2, data);
|
|
rhughes@241
|
579 |
|
|
rhughes@241
|
580 |
if (p1 != NULL && res <= 0)
|
|
rhughes@241
|
581 |
razor_package_iterator_next(pi1, &p1,
|
|
rhughes@241
|
582 |
&name1, &version1, &arch1);
|
|
rhughes@241
|
583 |
if (p2 != NULL && res >= 0)
|
|
rhughes@241
|
584 |
razor_package_iterator_next(pi2, &p2,
|
|
rhughes@241
|
585 |
&name2, &version2, &arch2);
|
|
rhughes@241
|
586 |
}
|
|
rhughes@241
|
587 |
|
|
rhughes@241
|
588 |
razor_package_iterator_destroy(pi1);
|
|
rhughes@241
|
589 |
razor_package_iterator_destroy(pi2);
|
|
rhughes@241
|
590 |
}
|
|
krh@254
|
591 |
|
|
krh@254
|
592 |
static void
|
|
krh@254
|
593 |
add_new_package(enum razor_diff_action action,
|
|
krh@254
|
594 |
struct razor_package *package,
|
|
krh@254
|
595 |
const char *name,
|
|
krh@254
|
596 |
const char *version,
|
|
krh@254
|
597 |
const char *arch,
|
|
krh@254
|
598 |
void *data)
|
|
krh@254
|
599 |
{
|
|
krh@254
|
600 |
if (action == RAZOR_DIFF_ACTION_ADD)
|
|
krh@254
|
601 |
razor_package_query_add_package(data, package);
|
|
krh@254
|
602 |
}
|
|
krh@254
|
603 |
|
|
krh@254
|
604 |
struct razor_package_iterator *
|
|
krh@254
|
605 |
razor_set_create_remove_iterator(struct razor_set *set,
|
|
krh@254
|
606 |
struct razor_set *next)
|
|
krh@254
|
607 |
{
|
|
krh@254
|
608 |
struct razor_package_query *query;
|
|
krh@254
|
609 |
struct razor_package_iterator *pi;
|
|
krh@254
|
610 |
|
|
krh@254
|
611 |
query = razor_package_query_create(set);
|
|
krh@254
|
612 |
razor_set_diff(next, set, add_new_package, query);
|
|
krh@254
|
613 |
|
|
krh@254
|
614 |
pi = razor_package_query_finish(query);
|
|
krh@254
|
615 |
|
|
krh@254
|
616 |
/* FIXME: We need to figure out the right install order here,
|
|
krh@254
|
617 |
* so the post and pre scripts can run. */
|
|
krh@254
|
618 |
|
|
krh@254
|
619 |
/* sort */
|
|
krh@254
|
620 |
|
|
krh@254
|
621 |
return pi;
|
|
krh@254
|
622 |
}
|
|
krh@254
|
623 |
|
|
krh@254
|
624 |
struct razor_package_iterator *
|
|
krh@254
|
625 |
razor_set_create_install_iterator(struct razor_set *set,
|
|
krh@254
|
626 |
struct razor_set *next)
|
|
krh@254
|
627 |
{
|
|
krh@254
|
628 |
struct razor_package_query *query;
|
|
krh@254
|
629 |
struct razor_package_iterator *pi;
|
|
krh@254
|
630 |
|
|
krh@254
|
631 |
query = razor_package_query_create(next);
|
|
krh@254
|
632 |
razor_set_diff(set, next, add_new_package, query);
|
|
krh@254
|
633 |
|
|
krh@254
|
634 |
pi = razor_package_query_finish(query);
|
|
krh@254
|
635 |
|
|
krh@254
|
636 |
/* FIXME: We need to figure out the right install order here,
|
|
krh@254
|
637 |
* so the post and pre scripts can run. */
|
|
krh@254
|
638 |
|
|
krh@254
|
639 |
/* sort */
|
|
krh@254
|
640 |
|
|
krh@254
|
641 |
return pi;
|
|
krh@254
|
642 |
}
|