Remove INTLLIBS from librazor_la_LIBADD.
This partially reverts 611c84a3f4b4538a65d186050608c17adbf17770.
It's not clear what motivated the initial inclusion of INTLLIBS
here since the net effect is only seen in librazor.la and not
in razor.pc and librazor.la is not normally packaged. Certainly
neither the static nor the dynamic versions of librazor currently
use libintl. At best this would cause the linker to search a
static libintl for undefined symbols without finding any; at worse
it causes a static build of plover using librazor.la to fail if
no static version of libintl is installed.
2 * Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
3 * Copyright (C) 2008 Red Hat, Inc
4 * Copyright (C) 2009, 2011, 2012 J. Ali Harlow <ali@juiblex.co.uk>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
29 #include <sys/types.h>
37 #include <winsock2.h> /* For ntohl() */
39 #include <arpa/inet.h>
46 #include "razor-internal.h"
52 #define RPM_LEAD_SIZE 96
55 PIPE = 1, /*!< pipe/fifo */
56 CDEV = 2, /*!< character device */
57 XDIR = 4, /*!< directory */
58 BDEV = 6, /*!< block device */
59 REG = 8, /*!< regular file */
60 LINK = 10, /*!< hard link */
61 SOCK = 12 /*!< socket */
65 RPMSENSE_LESS = 1 << 1,
66 RPMSENSE_GREATER = 1 << 2,
67 RPMSENSE_EQUAL = 1 << 3,
68 RPMSENSE_PREREQ = 1 << 6,
69 RPMSENSE_SCRIPT_PRE = 1 << 9,
70 RPMSENSE_SCRIPT_POST = 1 << 10,
71 RPMSENSE_SCRIPT_PREUN = 1 << 11,
72 RPMSENSE_SCRIPT_POSTUN = 1 << 12,
76 RPMTAG_NAME = 1000, /* s */
77 RPMTAG_VERSION = 1001, /* s */
78 RPMTAG_RELEASE = 1002, /* s */
79 RPMTAG_EPOCH = 1003, /* i */
80 RPMTAG_SUMMARY = 1004, /* s{} */
81 RPMTAG_DESCRIPTION = 1005, /* s{} */
82 RPMTAG_BUILDTIME = 1006, /* i */
83 RPMTAG_BUILDHOST = 1007, /* s */
84 RPMTAG_INSTALLTIME = 1008, /* i */
85 RPMTAG_SIZE = 1009, /* i */
86 RPMTAG_DISTRIBUTION = 1010, /* s */
87 RPMTAG_VENDOR = 1011, /* s */
88 RPMTAG_GIF = 1012, /* x */
89 RPMTAG_XPM = 1013, /* x */
90 RPMTAG_LICENSE = 1014, /* s */
91 RPMTAG_PACKAGER = 1015, /* s */
92 RPMTAG_GROUP = 1016, /* s{} */
93 RPMTAG_CHANGELOG = 1017, /*!< s[] internal */
94 RPMTAG_SOURCE = 1018, /* s[] */
95 RPMTAG_PATCH = 1019, /* s[] */
96 RPMTAG_URL = 1020, /* s */
97 RPMTAG_OS = 1021, /* s legacy used int */
98 RPMTAG_ARCH = 1022, /* s legacy used int */
99 RPMTAG_PREIN = 1023, /* s */
100 RPMTAG_POSTIN = 1024, /* s */
101 RPMTAG_PREUN = 1025, /* s */
102 RPMTAG_POSTUN = 1026, /* s */
103 RPMTAG_OLDFILENAMES = 1027, /* s[] obsolete */
104 RPMTAG_FILESIZES = 1028, /* i */
105 RPMTAG_FILESTATES = 1029, /* c */
106 RPMTAG_FILEMODES = 1030, /* h */
107 RPMTAG_FILEUIDS = 1031, /*!< internal */
108 RPMTAG_FILEGIDS = 1032, /*!< internal */
109 RPMTAG_FILERDEVS = 1033, /* h */
110 RPMTAG_FILEMTIMES = 1034, /* i */
111 RPMTAG_FILEMD5S = 1035, /* s[] */
112 RPMTAG_FILELINKTOS = 1036, /* s[] */
113 RPMTAG_FILEFLAGS = 1037, /* i */
114 RPMTAG_ROOT = 1038, /*!< internal - obsolete */
115 RPMTAG_FILEUSERNAME = 1039, /* s[] */
116 RPMTAG_FILEGROUPNAME = 1040, /* s[] */
117 RPMTAG_EXCLUDE = 1041, /*!< internal - obsolete */
118 RPMTAG_EXCLUSIVE = 1042, /*!< internal - obsolete */
120 RPMTAG_SOURCERPM = 1044, /* s */
121 RPMTAG_FILEVERIFYFLAGS = 1045, /* i */
122 RPMTAG_ARCHIVESIZE = 1046, /* i */
123 RPMTAG_PROVIDENAME = 1047, /* s[] */
124 RPMTAG_REQUIREFLAGS = 1048, /* i */
125 RPMTAG_REQUIRENAME = 1049, /* s[] */
126 RPMTAG_REQUIREVERSION = 1050, /* s[] */
127 RPMTAG_NOSOURCE = 1051, /*!< internal */
128 RPMTAG_NOPATCH = 1052, /*!< internal */
129 RPMTAG_CONFLICTFLAGS = 1053, /* i */
130 RPMTAG_CONFLICTNAME = 1054, /* s[] */
131 RPMTAG_CONFLICTVERSION = 1055, /* s[] */
132 RPMTAG_DEFAULTPREFIX = 1056, /*!< internal - deprecated */
133 RPMTAG_BUILDROOT = 1057, /*!< internal */
134 RPMTAG_INSTALLPREFIX = 1058, /*!< internal - deprecated */
135 RPMTAG_EXCLUDEARCH = 1059,
136 RPMTAG_EXCLUDEOS = 1060,
137 RPMTAG_EXCLUSIVEARCH = 1061,
138 RPMTAG_EXCLUSIVEOS = 1062,
139 RPMTAG_AUTOREQPROV = 1063, /*!< internal */
140 RPMTAG_RPMVERSION = 1064, /* s */
141 RPMTAG_TRIGGERSCRIPTS = 1065, /* s[] */
142 RPMTAG_TRIGGERNAME = 1066, /* s[] */
143 RPMTAG_TRIGGERVERSION = 1067, /* s[] */
144 RPMTAG_TRIGGERFLAGS = 1068, /* i */
145 RPMTAG_TRIGGERINDEX = 1069, /* i */
146 RPMTAG_VERIFYSCRIPT = 1079, /* s */
147 RPMTAG_CHANGELOGTIME = 1080, /* i */
148 RPMTAG_CHANGELOGNAME = 1081, /* s[] */
149 RPMTAG_CHANGELOGTEXT = 1082, /* s[] */
150 RPMTAG_BROKENMD5 = 1083, /*!< internal - obsolete */
151 RPMTAG_PREREQ = 1084, /*!< internal */
152 RPMTAG_PREINPROG = 1085, /* s */
153 RPMTAG_POSTINPROG = 1086, /* s */
154 RPMTAG_PREUNPROG = 1087, /* s */
155 RPMTAG_POSTUNPROG = 1088, /* s */
156 RPMTAG_BUILDARCHS = 1089,
157 RPMTAG_OBSOLETENAME = 1090, /* s[] */
158 RPMTAG_VERIFYSCRIPTPROG = 1091, /* s */
159 RPMTAG_TRIGGERSCRIPTPROG = 1092, /* s */
160 RPMTAG_DOCDIR = 1093, /*!< internal */
161 RPMTAG_COOKIE = 1094, /* s */
162 RPMTAG_FILEDEVICES = 1095, /* i */
163 RPMTAG_FILEINODES = 1096, /* i */
164 RPMTAG_FILELANGS = 1097, /* s[] */
165 RPMTAG_PREFIXES = 1098, /* s[] */
166 RPMTAG_INSTPREFIXES = 1099, /* s[] */
167 RPMTAG_TRIGGERIN = 1100, /*!< internal */
168 RPMTAG_TRIGGERUN = 1101, /*!< internal */
169 RPMTAG_TRIGGERPOSTUN = 1102, /*!< internal */
170 RPMTAG_AUTOREQ = 1103, /*!< internal */
171 RPMTAG_AUTOPROV = 1104, /*!< internal */
172 RPMTAG_CAPABILITY = 1105, /*!< internal - obsolete */
173 RPMTAG_SOURCEPACKAGE = 1106, /*!< i src.rpm header marker */
174 RPMTAG_OLDORIGFILENAMES = 1107, /*!< internal - obsolete */
175 RPMTAG_BUILDPREREQ = 1108, /*!< internal */
176 RPMTAG_BUILDREQUIRES = 1109, /*!< internal */
177 RPMTAG_BUILDCONFLICTS = 1110, /*!< internal */
178 RPMTAG_BUILDMACROS = 1111, /*!< internal - unused */
179 RPMTAG_PROVIDEFLAGS = 1112, /* i */
180 RPMTAG_PROVIDEVERSION = 1113, /* s[] */
181 RPMTAG_OBSOLETEFLAGS = 1114, /* i */
182 RPMTAG_OBSOLETEVERSION = 1115, /* s[] */
183 RPMTAG_DIRINDEXES = 1116, /* i */
184 RPMTAG_BASENAMES = 1117, /* s[] */
185 RPMTAG_DIRNAMES = 1118, /* s[] */
186 RPMTAG_ORIGDIRINDEXES = 1119, /*!< internal */
187 RPMTAG_ORIGBASENAMES = 1120, /*!< internal */
188 RPMTAG_ORIGDIRNAMES = 1121, /*!< internal */
189 RPMTAG_OPTFLAGS = 1122, /* s */
190 RPMTAG_DISTURL = 1123, /* s */
191 RPMTAG_PAYLOADFORMAT = 1124, /* s */
192 RPMTAG_PAYLOADCOMPRESSOR = 1125, /* s */
193 RPMTAG_PAYLOADFLAGS = 1126, /* s */
194 RPMTAG_INSTALLCOLOR = 1127, /*!< i transaction color when installed */
195 RPMTAG_INSTALLTID = 1128, /* i */
196 RPMTAG_REMOVETID = 1129, /* i */
197 RPMTAG_SHA1RHN = 1130, /*!< internal - obsolete */
198 RPMTAG_RHNPLATFORM = 1131, /* s */
199 RPMTAG_PLATFORM = 1132, /* s */
200 RPMTAG_PATCHESNAME = 1133, /*!< placeholder (SuSE) */
201 RPMTAG_PATCHESFLAGS = 1134, /*!< placeholder (SuSE) */
202 RPMTAG_PATCHESVERSION = 1135, /*!< placeholder (SuSE) */
203 RPMTAG_CACHECTIME = 1136, /* i */
204 RPMTAG_CACHEPKGPATH = 1137, /* s */
205 RPMTAG_CACHEPKGSIZE = 1138, /* i */
206 RPMTAG_CACHEPKGMTIME = 1139, /* i */
207 RPMTAG_FILECOLORS = 1140, /* i */
208 RPMTAG_FILECLASS = 1141, /* i */
209 RPMTAG_CLASSDICT = 1142, /* s[] */
210 RPMTAG_FILEDEPENDSX = 1143, /* i */
211 RPMTAG_FILEDEPENDSN = 1144, /* i */
212 RPMTAG_DEPENDSDICT = 1145, /* i */
213 RPMTAG_SOURCEPKGID = 1146, /* x */
214 RPMTAG_FILECONTEXTS = 1147, /* s[] */
215 RPMTAG_FSCONTEXTS = 1148, /*!< s[] extension */
216 RPMTAG_RECONTEXTS = 1149, /*!< s[] extension */
217 RPMTAG_POLICIES = 1150, /*!< s[] selinux *.te policy file. */
218 RPMTAG_PRETRANS = 1151, /* s */
219 RPMTAG_POSTTRANS = 1152, /* s */
220 RPMTAG_PRETRANSPROG = 1153, /* s */
221 RPMTAG_POSTTRANSPROG = 1154, /* s */
222 RPMTAG_DISTTAG = 1155, /* s */
223 RPMTAG_SUGGESTSNAME = 1156, /* s[] extension placeholder */
224 RPMTAG_SUGGESTSVERSION = 1157, /* s[] extension placeholder */
225 RPMTAG_SUGGESTSFLAGS = 1158, /* i extension placeholder */
226 RPMTAG_ENHANCESNAME = 1159, /* s[] extension placeholder */
227 RPMTAG_ENHANCESVERSION = 1160, /* s[] extension placeholder */
228 RPMTAG_ENHANCESFLAGS = 1161, /* i extension placeholder */
229 RPMTAG_PRIORITY = 1162, /* i extension placeholder */
230 RPMTAG_CVSID = 1163, /* s */
231 RPMTAG_TRIGGERPREIN = 1171, /*!< internal */
235 unsigned char magic[4];
236 unsigned char reserved[4];
241 struct rpm_header_index {
249 struct rpm_header *signature;
250 struct rpm_header *header;
252 unsigned int n_prefixes;
253 const char **prefixes;
258 struct razor_relocations *relocations;
262 enum razor_relocation_flags {
263 RAZOR_RELOCATION_ACTIVE = 1 << 0,
266 struct razor_relocation {
267 enum razor_relocation_flags flags;
274 struct razor_relocations {
275 /* Ordered such that if oldpath 1 starts with oldpath 2, then
276 * oldpath 1 is listed first (ie., /usr/bin comes before /usr)
277 * and terminated with a NULL oldpath.
279 struct razor_relocation *relocations;
284 RAZOR_EXPORT struct razor_relocations *razor_relocations_create(void)
286 return calloc(1, sizeof(struct razor_relocations));
289 RAZOR_EXPORT void razor_relocations_add(struct razor_relocations *rr,
290 const char *oldpath, const char *newpath)
295 if (newpath && !strcmp(oldpath, newpath))
298 for (i = 0; i < rr->n_relocations; i++) {
299 len = rr->relocations[i].oldlen;
300 if (!strncmp(rr->relocations[i].oldpath, oldpath, len)) {
301 found = !strcmp(rr->relocations[i].oldpath, oldpath);
308 free(rr->relocations[i].oldpath);
309 free(rr->relocations[i].newpath);
311 rr->relocations[i] = rr->relocations[i + 1];
312 } while (rr->relocations[++i].oldpath);
318 free(rr->relocations[i].newpath);
319 rr->relocations[i].newpath = strdup(newpath);
320 rr->relocations[i].newlen = strlen(newpath);
324 if (!rr->n_relocations++)
325 rr->relocations = calloc(1, sizeof *rr->relocations);
327 rr->relocations = realloc(rr->relocations,
328 rr->n_relocations * sizeof *rr->relocations);
329 memmove(rr->relocations + i + 1, rr->relocations + i,
330 (rr->n_relocations - i - 1) * sizeof *rr->relocations);
333 rr->relocations[i].flags = 0;
334 rr->relocations[i].oldpath = strdup(oldpath);
335 rr->relocations[i].newpath = strdup(newpath);
336 rr->relocations[i].oldlen = strlen(oldpath);
337 rr->relocations[i].newlen = strlen(newpath);
341 razor_relocations_set_rpm(struct razor_relocations *rr, struct razor_rpm *rpm)
345 for (i = 0; i < rr->n_relocations; i++) {
346 rr->relocations[i].flags &= ~RAZOR_RELOCATION_ACTIVE;
347 for (j = 0; j < rpm->n_prefixes; j++)
348 if (!strcmp(rpm->prefixes[j],
349 rr->relocations[i].oldpath)) {
350 rr->relocations[i].flags |= RAZOR_RELOCATION_ACTIVE;
356 RAZOR_EXPORT const char *
357 razor_relocations_apply(struct razor_relocations *rr, const char *path)
362 for (i = 0; i < rr->n_relocations; i++)
363 if (rr->relocations[i].flags & RAZOR_RELOCATION_ACTIVE &&
364 !strncmp(path, rr->relocations[i].oldpath,
365 rr->relocations[i].oldlen))
368 if (i < rr->n_relocations) {
370 len = strlen(path + rr->relocations[i].oldlen) +
371 rr->relocations[i].newlen;
372 rr->path = malloc(len + 1);
373 memcpy(rr->path, rr->relocations[i].newpath,
374 rr->relocations[i].newlen);
375 strcpy(rr->path + rr->relocations[i].newlen,
376 path + rr->relocations[i].oldlen);
382 RAZOR_EXPORT void razor_relocations_destroy(struct razor_relocations *rr)
385 free(rr->relocations);
389 static struct rpm_header_index *
390 razor_rpm_get_header(struct razor_rpm *rpm, unsigned int tag)
392 struct rpm_header_index *index, *end;
394 index = (struct rpm_header_index *) (rpm->header + 1);
395 end = index + ntohl(rpm->header->nindex);
396 while (index < end) {
397 if (ntohl(index->tag) == tag)
406 razor_rpm_get_indirect(struct razor_rpm *rpm,
407 unsigned int tag, unsigned int *count)
409 struct rpm_header_index *index;
411 index = razor_rpm_get_header(rpm, tag);
414 *count = ntohl(index->count);
416 return rpm->pool + ntohl(index->offset);
423 rpm_to_razor_flags(uint32_t flags)
425 uint32_t razor_flags;
428 if (flags & RPMSENSE_LESS)
429 razor_flags |= RAZOR_PROPERTY_LESS;
430 if (flags & RPMSENSE_EQUAL)
431 razor_flags |= RAZOR_PROPERTY_EQUAL;
432 if (flags & RPMSENSE_GREATER)
433 razor_flags |= RAZOR_PROPERTY_GREATER;
435 if (flags & RPMSENSE_SCRIPT_PRE)
436 razor_flags |= RAZOR_PROPERTY_PRE;
437 if (flags & RPMSENSE_SCRIPT_POST)
438 razor_flags |= RAZOR_PROPERTY_POST;
439 if (flags & RPMSENSE_SCRIPT_PREUN)
440 razor_flags |= RAZOR_PROPERTY_PREUN;
441 if (flags & RPMSENSE_SCRIPT_POSTUN)
442 razor_flags |= RAZOR_PROPERTY_POSTUN;
448 import_properties(struct razor_importer *importer, uint32_t type,
449 struct razor_rpm *rpm,
450 int name_tag, int version_tag, int flags_tag)
452 const char *name, *version;
453 const uint32_t *flags;
455 unsigned int i, count;
457 name = razor_rpm_get_indirect(rpm, name_tag, &count);
461 flags = razor_rpm_get_indirect(rpm, flags_tag, &count);
463 version = razor_rpm_get_indirect(rpm, version_tag, &count);
464 for (i = 0; i < count; i++) {
465 f = rpm_to_razor_flags(ntohl(flags[i]));
466 razor_importer_add_property(importer, name, f | type, version);
467 name += strlen(name) + 1;
468 version += strlen(version) + 1;
473 import_files(struct razor_importer *importer, struct razor_rpm *rpm)
476 const uint32_t *index;
477 unsigned int i, count;
480 if (rpm->dirs == NULL)
483 /* assert: count is the same for all arrays */
484 index = razor_rpm_get_indirect(rpm, RPMTAG_DIRINDEXES, &count);
485 name = razor_rpm_get_indirect(rpm, RPMTAG_BASENAMES, &count);
486 for (i = 0; i < count; i++) {
487 snprintf(buffer, sizeof buffer,
488 "%s%s", rpm->dirs[ntohl(*index)], name);
489 razor_importer_add_file(importer, buffer);
490 name += strlen(name) + 1;
496 razor_rpm_build_evr(struct razor_rpm *rpm)
498 const char *version, *release;
499 const uint32_t *epoch;
500 char evr[128], buf[16];
502 epoch = razor_rpm_get_indirect(rpm, RPMTAG_EPOCH, NULL);
503 version = razor_rpm_get_indirect(rpm, RPMTAG_VERSION, NULL);
504 release = razor_rpm_get_indirect(rpm, RPMTAG_RELEASE, NULL);
506 snprintf(buf, sizeof buf, "%lu", (unsigned long)ntohl(*epoch));
507 razor_build_evr(evr, sizeof evr, epoch ? buf : NULL, version, release);
508 rpm->evr = strdup(evr);
512 razor_rpm_get_details_string(struct razor_rpm *rpm, enum razor_detail_type type)
515 case RAZOR_DETAIL_NAME:
516 return razor_rpm_get_indirect(rpm, RPMTAG_NAME, NULL);
518 case RAZOR_DETAIL_VERSION:
520 razor_rpm_build_evr(rpm);
523 case RAZOR_DETAIL_ARCH:
524 return razor_rpm_get_indirect(rpm, RPMTAG_ARCH, NULL);
526 case RAZOR_DETAIL_SUMMARY:
527 return razor_rpm_get_indirect(rpm, RPMTAG_SUMMARY, NULL);
529 case RAZOR_DETAIL_DESCRIPTION:
530 return razor_rpm_get_indirect(rpm, RPMTAG_DESCRIPTION, NULL);
532 case RAZOR_DETAIL_URL:
533 return razor_rpm_get_indirect(rpm, RPMTAG_URL, NULL);
535 case RAZOR_DETAIL_LICENSE:
536 return razor_rpm_get_indirect(rpm, RPMTAG_LICENSE, NULL);
538 case RAZOR_DETAIL_PREUNPROG:
539 return razor_rpm_get_indirect(rpm, RPMTAG_PREUNPROG, NULL);
541 case RAZOR_DETAIL_PREUN:
542 return razor_rpm_get_indirect(rpm, RPMTAG_PREUN, NULL);
544 case RAZOR_DETAIL_POSTUNPROG:
545 return razor_rpm_get_indirect(rpm, RPMTAG_POSTUNPROG, NULL);
547 case RAZOR_DETAIL_POSTUN:
548 return razor_rpm_get_indirect(rpm, RPMTAG_POSTUN, NULL);
551 fprintf(stderr, "type %u not found\n", type);
556 static const char *const *
557 razor_rpm_get_details_array(struct razor_rpm *rpm, enum razor_detail_type type)
560 case RAZOR_DETAIL_PREFIXES:
561 return rpm->prefixes;
565 fprintf(stderr, "type %u not found\n", type);
571 razor_rpm_get_details_varg(struct razor_rpm *rpm, va_list args)
574 enum razor_detail_type type;
576 const char *const **array;
578 for (i = 0;; i += 2) {
579 type = va_arg(args, enum razor_detail_type);
580 if (type == RAZOR_DETAIL_LAST)
582 if (type == RAZOR_DETAIL_PREFIXES) {
583 array = va_arg(args, const char *const **);
584 *array = razor_rpm_get_details_array(rpm, type);
586 string = va_arg(args, const char **);
587 *string = razor_rpm_get_details_string(rpm, type);
593 razor_rpm_get_details(struct razor_rpm *rpm, ...)
600 razor_rpm_get_details_varg(rpm, args);
604 RAZOR_EXPORT struct razor_rpm *
605 razor_rpm_open(const char *filename, struct razor_error **error)
607 struct razor_rpm *rpm;
608 struct rpm_header_index *base, *index;
609 unsigned int count, i, nindex, hsize;
610 const char *name, *prefix;
612 assert (filename != NULL);
614 rpm = zalloc(sizeof *rpm);
616 razor_set_error(error, NULL, "Not enough memory");
619 memset(rpm, 0, sizeof *rpm);
621 rpm->map = razor_file_get_contents(filename, &rpm->size, 0, error);
627 rpm->signature = rpm->map + RPM_LEAD_SIZE;
628 nindex = ntohl(rpm->signature->nindex);
629 hsize = ntohl(rpm->signature->hsize);
630 rpm->header = (void *) (rpm->signature + 1) +
631 ALIGN(nindex * sizeof *index + hsize, 8);
632 nindex = ntohl(rpm->header->nindex);
633 hsize = ntohl(rpm->header->hsize);
634 rpm->payload = (void *) (rpm->header + 1) +
635 nindex * sizeof *index + hsize;
637 base = (struct rpm_header_index *) (rpm->header + 1);
638 rpm->pool = (void *) base + nindex * sizeof *index;
640 /* Look up dir names now so we can index them directly. */
641 name = razor_rpm_get_indirect(rpm, RPMTAG_DIRNAMES, &count);
643 rpm->dirs = calloc(count, sizeof *rpm->dirs);
644 for (i = 0; i < count; i++) {
646 name += strlen(name) + 1;
649 name = razor_rpm_get_indirect(rpm, RPMTAG_OLDFILENAMES,
652 razor_rpm_close(rpm);
653 razor_set_error(error, filename,
654 "Old filenames not supported");
659 prefix = razor_rpm_get_indirect(rpm, RPMTAG_PREFIXES, &count);
661 rpm->prefixes = calloc(count + 1, sizeof *rpm->prefixes);
662 for (i = 0; i < count; i++) {
663 rpm->prefixes[i] = prefix;
664 prefix += strlen(prefix) + 1;
666 rpm->prefixes[i] = NULL;
667 rpm->n_prefixes = count;
669 prefix = razor_rpm_get_indirect(rpm, RPMTAG_DEFAULTPREFIX,
672 razor_rpm_close(rpm);
673 razor_set_error(error, filename,
674 "Default prefix not supported");
682 RAZOR_EXPORT void razor_rpm_set_relocations(struct razor_rpm *rpm,
683 struct razor_relocations *rr)
685 assert (rpm != NULL);
687 rpm->relocations = rr;
690 struct cpio_file_header {
709 #define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
710 #define HEAD_CRC 0x02 /* bit 1 set: header CRC present */
711 #define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
712 #define ORIG_NAME 0x08 /* bit 3 set: original file name present */
713 #define COMMENT 0x10 /* bit 4 set: file comment present */
714 #define RESERVED 0xE0 /* bits 5..7: reserved */
718 struct razor_rpm *rpm;
719 struct razor_atomic *atomic;
721 unsigned char buffer[32768];
726 installer_inflate(struct installer *installer)
731 if (installer->rest > sizeof installer->buffer)
732 length = sizeof installer->buffer;
734 length = installer->rest;
736 installer->stream.next_out = installer->buffer;
737 installer->stream.avail_out = length;
738 err = inflate(&installer->stream, Z_SYNC_FLUSH);
739 if (err != Z_OK && err != Z_STREAM_END) {
740 razor_atomic_abort(installer->atomic, "Failed to inflate");
744 installer->rest -= length;
745 installer->length = length;
751 installer_align(struct installer *installer, size_t size)
753 unsigned char buffer[4];
756 installer->stream.next_out = buffer;
757 installer->stream.avail_out =
758 (size - installer->stream.total_out) & (size - 1);
760 if (installer->stream.avail_out == 0)
763 err = inflate(&installer->stream, Z_SYNC_FLUSH);
764 if (err != Z_OK && err != Z_STREAM_END) {
765 razor_atomic_abort(installer->atomic, "Failed to inflate");
773 create_path(struct installer *installer, const char *path, unsigned int mode)
778 if (razor_atomic_make_dirs(installer->atomic, installer->root, path))
781 buffer = razor_concat(installer->root, path, NULL);
783 switch (mode >> 12) {
785 /* FIXME: handle the case where a file is already there. */
786 h = razor_atomic_create_file(installer->atomic, buffer, mode);
790 while (installer->rest > 0) {
791 if (installer_inflate(installer))
793 if (razor_atomic_write(installer->atomic, h,
798 return razor_atomic_close(installer->atomic, h);
800 ret = razor_atomic_create_dir(installer->atomic, buffer, mode);
805 if (installer_inflate(installer))
807 if (installer->length >= sizeof installer->buffer) {
808 razor_atomic_abort(installer->atomic,
809 "Link target too long");
812 installer->buffer[installer->length] = '\0';
813 ret = razor_atomic_create_symlink(installer->atomic,
814 (const char *)installer->buffer, buffer);
818 s = "Symbolic links";
825 buffer = razor_concat(s, " are not supported on this platform",
827 razor_atomic_abort(installer->atomic, buffer);
831 s = "Character devices";
841 razor_atomic_abort(installer->atomic, "Unknown file type");
846 static int chroot_push(const char *root)
850 if (geteuid() == 0) {
851 fd = open("/", O_RDONLY, 0);
852 if (chroot(root) < 0) {
853 fprintf(stderr, "failed to chroot to %s: %s\n",
854 root, strerror(errno));
863 static void chroot_pop(int fd)
875 run_script_lua(const char *root, unsigned int script_tag, const char *script,
899 root_fd = chroot_push(root);
900 retval = run_lua_script(root_fd < 0 ? root : NULL, name, script, -1,
904 fprintf(stderr, "lua not available to run script\n");
906 #endif /* HAVE_LUA */
912 run_script_external(const char *root, const char *program, const char *script,
917 char buf[32], *command;
919 if (program == NULL) {
921 program = getenv("COMSPEC");
923 program = strchr(program, '=');
928 program = "c:\\windows\\system32\\cmd.exe";
934 root_fd = chroot_push(root);
936 sprintf(buf, "%d", arg1);
937 command = malloc(strlen(program) + strlen(buf) + 2);
938 sprintf(command, "%s %s", program, buf);
940 command = strdup(program);
941 fp = popen(command, "w");
947 } else if (script && fwrite(script, strlen(script), 1, fp) != 1) {
948 perror("failed to write script to program");
961 run_script(struct installer *installer,
962 unsigned int program_tag, unsigned int script_tag, int arg1)
965 struct razor_rpm *rpm = installer->rpm;
966 const char *script = NULL, *program = NULL, *prefix;
968 struct environment env;
970 program = razor_rpm_get_indirect(rpm, program_tag, NULL);
971 script = razor_rpm_get_indirect(rpm, script_tag, NULL);
972 if (program == NULL && script == NULL)
975 if (rpm->relocations) {
976 environment_init(&env);
977 for(i = 0; i < rpm->n_prefixes; i++) {
978 prefix = razor_relocations_apply(rpm->relocations,
980 sprintf(buf, "RPM_INSTALL_PREFIX%d", i);
981 environment_add_variable(&env, buf, prefix);
983 environment_set(&env);
986 if (program && strcmp(program, "<lua>") == 0)
987 retval = run_script_lua(installer->root, script_tag, script,
990 retval = run_script_external(installer->root, program, script,
993 if (rpm->relocations) {
994 environment_unset(&env);
995 environment_release(&env);
1002 razor_run_script(const char *root, enum razor_property_flags script,
1003 const char *program, const char *body, int arg1)
1006 unsigned int script_tag;
1008 if (program && !*program)
1012 if (program == NULL && body == NULL)
1015 if (program && strcmp(program, "<lua>") == 0)
1018 case RAZOR_PROPERTY_PRE:
1019 script_tag = RPMTAG_PREIN;
1021 case RAZOR_PROPERTY_POST:
1022 script_tag = RPMTAG_POSTIN;
1024 case RAZOR_PROPERTY_PREUN:
1025 script_tag = RPMTAG_PREUN;
1027 case RAZOR_PROPERTY_POSTUN:
1028 script_tag = RPMTAG_POSTUN;
1034 retval = run_script_lua(root, script_tag, body, arg1);
1037 retval = run_script_external(root, program, body, arg1);
1043 installer_init(struct installer *installer)
1045 unsigned char *gz_header;
1046 int method, flags, err;
1047 char buffer[32], *s;
1049 gz_header = installer->rpm->payload;
1050 if (gz_header[0] != 0x1f || gz_header[1] != 0x8b) {
1051 razor_atomic_abort(installer->atomic,
1052 "Payload section doesn't have gz header");
1056 method = gz_header[2];
1057 flags = gz_header[3];
1059 if (method != Z_DEFLATED || flags != 0) {
1060 razor_atomic_abort(installer->atomic,
1061 "Unknown payload compression method or "
1066 installer->stream.zalloc = NULL;
1067 installer->stream.zfree = NULL;
1068 installer->stream.opaque = NULL;
1070 installer->stream.next_in = gz_header + 10;
1071 installer->stream.avail_in =
1072 (installer->rpm->map + installer->rpm->size) -
1073 (void *) installer->stream.next_in;
1074 installer->stream.next_out = NULL;
1075 installer->stream.avail_out = 0;
1077 err = inflateInit2(&installer->stream, -MAX_WBITS);
1079 sprintf(buffer, "%d", err);
1080 s = razor_concat("inflateEnd error: ", s, NULL);
1081 razor_atomic_abort(installer->atomic, s);
1090 installer_finish(struct installer *installer)
1093 char buffer[32], *s;
1095 err = inflateEnd(&installer->stream);
1098 sprintf(buffer, "%d", err);
1099 s = razor_concat("inflateEnd error: ", s, NULL);
1100 razor_atomic_abort(installer->atomic, s);
1104 return razor_atomic_in_error_state(installer->atomic);
1107 static unsigned long
1108 fixed_hex_to_ulong(const char *hex, int length)
1113 for (i = 0, l = 0; i < length; i++) {
1115 l = l * 16 + hex[i] - '0';
1117 l = l * 16 + hex[i] - 'a' + 10;
1124 razor_rpm_install(struct razor_rpm *rpm, struct razor_atomic *atomic,
1125 const char *root, int install_count,
1126 enum razor_stage_type stage)
1128 struct installer installer;
1129 struct cpio_file_header *header;
1137 assert (rpm != NULL);
1138 assert (root != NULL);
1140 installer.rpm = rpm;
1141 installer.root = root;
1142 installer.atomic = atomic;
1144 /* FIXME: Only do this before a transaction, not per rpm. */
1145 if (*root && (stat(root, &buf) < 0 || !S_ISDIR(buf.st_mode))) {
1146 s = razor_concat(root, ": Directory does not exist", NULL);
1147 razor_atomic_abort(atomic, s);
1152 if (rpm->relocations)
1153 razor_relocations_set_rpm(rpm->relocations, rpm);
1155 if (stage & RAZOR_STAGE_SCRIPTS_PRE)
1156 retval = run_script(&installer, RPMTAG_PREINPROG, RPMTAG_PREIN,
1159 if (!retval && (stage & RAZOR_STAGE_FILES)) {
1160 if (installer_init(&installer))
1163 while (installer.stream.avail_in > 0) {
1164 installer.rest = sizeof *header;
1165 if (installer_inflate(&installer))
1168 header = (struct cpio_file_header *) installer.buffer;
1169 mode = fixed_hex_to_ulong(header->mode,
1170 sizeof header->mode);
1171 filesize = fixed_hex_to_ulong(header->filesize,
1172 sizeof header->filesize);
1175 fixed_hex_to_ulong(header->namesize,
1176 sizeof header->namesize);
1178 if (installer_inflate(&installer) ||
1179 installer_align(&installer, 4))
1182 path = (const char *) installer.buffer;
1183 /* This convention is so lame... */
1184 if (strcmp(path, "TRAILER!!!") == 0)
1187 installer.rest = filesize;
1189 if (rpm->relocations)
1190 path = razor_relocations_apply(rpm->relocations,
1192 if (create_path(&installer, path, mode))
1194 if (installer_align(&installer, 4))
1198 if (installer_finish(&installer))
1201 retval = razor_atomic_in_error_state(atomic);
1204 if (!retval && (stage & RAZOR_STAGE_SCRIPTS_POST))
1205 retval = run_script(&installer, RPMTAG_POSTINPROG,
1206 RPMTAG_POSTIN, install_count);
1212 razor_rpm_close(struct razor_rpm *rpm)
1216 assert (rpm != NULL);
1219 free(rpm->prefixes);
1220 err = razor_file_free_contents(rpm->map, rpm->size);
1228 razor_importer_add_rpm(struct razor_importer *importer, struct razor_rpm *rpm)
1230 const char *name, *version, *arch;
1231 const char *summary, *description, *url, *license;
1233 assert (importer != NULL);
1234 assert (rpm != NULL);
1236 razor_rpm_get_details(rpm,
1237 RAZOR_DETAIL_NAME, &name,
1238 RAZOR_DETAIL_VERSION, &version,
1239 RAZOR_DETAIL_ARCH, &arch,
1240 RAZOR_DETAIL_SUMMARY, &summary,
1241 RAZOR_DETAIL_DESCRIPTION, &description,
1242 RAZOR_DETAIL_URL, &url,
1243 RAZOR_DETAIL_LICENSE, &license,
1246 razor_importer_begin_package(importer, name, version, arch);
1248 razor_importer_add_details(importer, summary, description, url,
1251 import_properties(importer, RAZOR_PROPERTY_REQUIRES, rpm,
1253 RPMTAG_REQUIREVERSION,
1254 RPMTAG_REQUIREFLAGS);
1256 import_properties(importer, RAZOR_PROPERTY_PROVIDES, rpm,
1258 RPMTAG_PROVIDEVERSION,
1259 RPMTAG_PROVIDEFLAGS);
1261 import_properties(importer, RAZOR_PROPERTY_OBSOLETES, rpm,
1262 RPMTAG_OBSOLETENAME,
1263 RPMTAG_OBSOLETEVERSION,
1264 RPMTAG_OBSOLETEFLAGS);
1266 import_properties(importer, RAZOR_PROPERTY_CONFLICTS, rpm,
1267 RPMTAG_CONFLICTNAME,
1268 RPMTAG_CONFLICTVERSION,
1269 RPMTAG_CONFLICTFLAGS);
1271 import_files(importer, rpm);
1273 razor_importer_finish_package(importer);