src/import-rpmdb.c
author J. Ali Harlow <ali@juiblex.co.uk>
Thu Feb 09 20:45:27 2012 +0000 (2012-02-09)
changeset 418 33b825d3128d
parent 369 f8c27fe9fe63
child 438 fab0b8a61dcb
permissions -rw-r--r--
Add transaction barriers
These allow packages to be installed and removed which have scripts
that depend on each other when atomic transactions are involved.
Note that yum supports pre, but not other requires flags. post will
need similar support to the post scripts themselves pulling in the
requires flags from the rpms. Likewise preun and postun will need
similar handling to those scrips since the requires flags will need
to be stored in the razor database.
     1 /*
     2  * Copyright (C) 2008  Kristian Høgsberg <krh@redhat.com>
     3  * Copyright (C) 2008  Red Hat, Inc
     4  * Copyright (C) 2009  J. Ali Harlow <ali@juiblex.co.uk>
     5  *
     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.
    10  *
    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.
    15  *
    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.
    19  */
    20 
    21 #include <stdio.h>
    22 #include <stddef.h>
    23 #include <string.h>
    24 #include <fcntl.h>
    25 #include <limits.h>
    26 #include <rpm/rpmlib.h>
    27 #include <rpm/rpmdb.h>
    28 
    29 #include "razor.h"
    30 
    31 union rpm_entry {
    32 	void *p;
    33 	char *string;
    34 	char **list;
    35 	uint32_t *flags;
    36 	uint32_t integer;
    37 };
    38 
    39 static uint32_t
    40 rpm_to_razor_flags(uint32_t flags)
    41 {
    42 	uint32_t razor_flags;
    43 
    44 	razor_flags = 0;
    45 	if (flags & RPMSENSE_LESS)
    46 		razor_flags |= RAZOR_PROPERTY_LESS;
    47 	if (flags & RPMSENSE_EQUAL)
    48 		razor_flags |= RAZOR_PROPERTY_EQUAL;
    49 	if (flags & RPMSENSE_GREATER)
    50 		razor_flags |= RAZOR_PROPERTY_GREATER;
    51 
    52 	if (flags & RPMSENSE_SCRIPT_PRE)
    53 		razor_flags |= RAZOR_PROPERTY_PRE;
    54 	if (flags & RPMSENSE_SCRIPT_POST)
    55 		razor_flags |= RAZOR_PROPERTY_POST;
    56 	if (flags & RPMSENSE_SCRIPT_PREUN)
    57 		razor_flags |= RAZOR_PROPERTY_PREUN;
    58 	if (flags & RPMSENSE_SCRIPT_POSTUN)
    59 		razor_flags |= RAZOR_PROPERTY_POSTUN;
    60 
    61 	return razor_flags;
    62 }
    63 
    64 static void
    65 add_properties(struct razor_importer *importer,
    66 	       uint32_t type_flags, Header h,
    67 	       int32_t name_tag, int32_t version_tag, int32_t flags_tag)
    68 {
    69 	union rpm_entry names, versions, flags;
    70 	int32_t i, type, count;
    71 
    72 	headerGetEntry(h, name_tag, &type, &names.p, &count);
    73 	headerGetEntry(h, version_tag, &type, &versions.p, &count);
    74 	headerGetEntry(h, flags_tag, &type, &flags.p, &count);
    75 
    76 	for (i = 0; i < count; i++)
    77 		razor_importer_add_property(importer,
    78 					    names.list[i],
    79 					    rpm_to_razor_flags (flags.flags[i]) | type_flags,
    80 					    versions.list[i]);
    81 }
    82 
    83 static void
    84 add_script(struct razor_importer *importer,
    85 	   uint32_t type_flags, Header h,
    86 	   int32_t program_tag, int32_t body_tag)
    87 {
    88 	union rpm_entry program, body;
    89 	int32_t type, count;
    90 
    91 	headerGetEntry(h, program_tag, &type, &program.p, &count);
    92 	headerGetEntry(h, body_tag, &type, &body.p, &count);
    93 
    94 	razor_importer_add_script(importer, type_flags,
    95 				  program.string, body.string);
    96 }
    97 
    98 struct razor_set *
    99 razor_set_create_from_rpmdb(void)
   100 {
   101 	struct razor_importer *importer;
   102 	rpmdbMatchIterator iter;
   103 	Header h;
   104 	int32_t type, count, i;
   105 	union rpm_entry name, epoch, version, release, arch;
   106 	union rpm_entry summary, description, url, license;
   107 	union rpm_entry basenames, dirnames, dirindexes;
   108 	union rpm_entry install_prefixes;
   109 	char filename[PATH_MAX], evr[128], buf[16];
   110 	rpmdb db;
   111 	int imported_count = 0;
   112 
   113 	rpmReadConfigFiles(NULL, NULL);
   114 
   115 	if (rpmdbOpen("", &db, O_RDONLY, 0644) != 0) {
   116 		fprintf(stderr, "cannot open rpm database\n");
   117 		exit(1);
   118 	}
   119 
   120 	importer = razor_importer_create();
   121 
   122 	iter = rpmdbInitIterator(db, 0, NULL, 0);
   123 	while (h = rpmdbNextIterator(iter), h != NULL) {
   124 		headerGetEntry(h, RPMTAG_NAME, &type, &name.p, &count);
   125 		headerGetEntry(h, RPMTAG_EPOCH, &type, &epoch.p, &count);
   126 		headerGetEntry(h, RPMTAG_VERSION, &type, &version.p, &count);
   127 		headerGetEntry(h, RPMTAG_RELEASE, &type, &release.p, &count);
   128 		headerGetEntry(h, RPMTAG_ARCH, &type, &arch.p, &count);
   129 		headerGetEntry(h, RPMTAG_SUMMARY, &type, &summary.p, &count);
   130 		headerGetEntry(h, RPMTAG_DESCRIPTION, &type, &description.p,
   131 			       &count);
   132 		headerGetEntry(h, RPMTAG_URL, &type, &url.p, &count);
   133 		headerGetEntry(h, RPMTAG_LICENSE, &type, &license.p, &count);
   134 
   135 		if (epoch.flags != NULL) {
   136 			snprintf(buf, sizeof buf, "%u", *epoch.flags);
   137 			razor_build_evr(evr, sizeof evr,
   138 					buf, version.string, release.string);
   139 		} else {
   140 			razor_build_evr(evr, sizeof evr,
   141 					NULL, version.string, release.string);
   142 		}
   143 
   144 		razor_importer_begin_package(importer,
   145 					     name.string, evr, arch.string);
   146 		razor_importer_add_details(importer, summary.string,
   147 					   description.string, url.string,
   148 					   license.string);
   149 
   150 		add_properties(importer, RAZOR_PROPERTY_REQUIRES, h,
   151 			       RPMTAG_REQUIRENAME,
   152 			       RPMTAG_REQUIREVERSION,
   153 			       RPMTAG_REQUIREFLAGS);
   154 
   155 		add_properties(importer, RAZOR_PROPERTY_PROVIDES, h,
   156 			       RPMTAG_PROVIDENAME,
   157 			       RPMTAG_PROVIDEVERSION,
   158 			       RPMTAG_PROVIDEFLAGS);
   159 
   160 		add_properties(importer, RAZOR_PROPERTY_OBSOLETES, h,
   161 			       RPMTAG_OBSOLETENAME,
   162 			       RPMTAG_OBSOLETEVERSION,
   163 			       RPMTAG_OBSOLETEFLAGS);
   164 
   165 		add_properties(importer, RAZOR_PROPERTY_CONFLICTS, h,
   166 			       RPMTAG_CONFLICTNAME,
   167 			       RPMTAG_CONFLICTVERSION,
   168 			       RPMTAG_CONFLICTFLAGS);
   169 
   170 		headerGetEntry(h, RPMTAG_BASENAMES, &type,
   171 			       &basenames.p, &count);
   172 		headerGetEntry(h, RPMTAG_DIRNAMES, &type,
   173 			       &dirnames.p, &count);
   174 		headerGetEntry(h, RPMTAG_DIRINDEXES, &type,
   175 			       &dirindexes.p, &count);
   176 		for (i = 0; i < count; i++) {
   177 			snprintf(filename, sizeof filename, "%s%s",
   178 				 dirnames.list[dirindexes.flags[i]],
   179 				 basenames.list[i]);
   180 			razor_importer_add_file(importer, filename);
   181 		}
   182 
   183 		add_script(importer, RAZOR_PROPERTY_PREUN, h,
   184 			   RPMTAG_PREUNPROG, RPMTAG_PREUN);
   185 
   186 		add_script(importer, RAZOR_PROPERTY_POSTUN, h,
   187 			   RPMTAG_POSTUNPROG, RPMTAG_POSTUN);
   188 
   189 		headerGetEntry(h, RPMTAG_INSTPREFIXES, &type,
   190 			       &install_prefixes.p, &count);
   191 		for (i = 0; i < count; i++)
   192 			razor_importer_add_install_prefix(importer,
   193 							  install_prefixes.list[i]);
   194 
   195 		razor_importer_finish_package(importer);
   196 
   197 		printf("\rimporting %d", ++imported_count);
   198 		fflush(stdout);
   199 	}
   200 
   201 	rpmdbClose(db);
   202 
   203 	printf("\nsaving\n");
   204 	return razor_importer_finish(importer);
   205 }