src/import-rpmdb.c
author J. Ali Harlow <ali@juiblex.co.uk>
Thu Oct 09 17:27:41 2014 +0100 (2014-10-09)
changeset 455 df914f383f5c
parent 372 6e93e5485947
child 475 008c75a5e08d
permissions -rw-r--r--
Support downloading from local repository even without libcurl

Using the --url option of the razor executable, it is possible
to specify a yum repository on the local machine (eg., on installation
media) and import from there, eg.,:

C> razor --url file:///d:/ import-yum

This will be handled by libcurl if available but if not, an internal
copy routine will be used.

Note that if Microsoft's KTM implementation of atomic transactions is
used, then the current directory must support atomic transactions
(also improve error messages for this, and other, cases).
     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 "config.h"
    22 #include <stdio.h>
    23 #include <stddef.h>
    24 #include <string.h>
    25 #include <fcntl.h>
    26 #include <limits.h>
    27 #include <rpm/rpmlib.h>
    28 #include <rpm/rpmdb.h>
    29 
    30 #include "razor.h"
    31 
    32 union rpm_entry {
    33 	void *p;
    34 	char *string;
    35 	char **list;
    36 	uint32_t *flags;
    37 	uint32_t integer;
    38 };
    39 
    40 static uint32_t
    41 rpm_to_razor_flags(uint32_t flags)
    42 {
    43 	uint32_t razor_flags;
    44 
    45 	razor_flags = 0;
    46 	if (flags & RPMSENSE_LESS)
    47 		razor_flags |= RAZOR_PROPERTY_LESS;
    48 	if (flags & RPMSENSE_EQUAL)
    49 		razor_flags |= RAZOR_PROPERTY_EQUAL;
    50 	if (flags & RPMSENSE_GREATER)
    51 		razor_flags |= RAZOR_PROPERTY_GREATER;
    52 
    53 	if (flags & RPMSENSE_SCRIPT_PRE)
    54 		razor_flags |= RAZOR_PROPERTY_PRE;
    55 	if (flags & RPMSENSE_SCRIPT_POST)
    56 		razor_flags |= RAZOR_PROPERTY_POST;
    57 	if (flags & RPMSENSE_SCRIPT_PREUN)
    58 		razor_flags |= RAZOR_PROPERTY_PREUN;
    59 	if (flags & RPMSENSE_SCRIPT_POSTUN)
    60 		razor_flags |= RAZOR_PROPERTY_POSTUN;
    61 
    62 	return razor_flags;
    63 }
    64 
    65 static void
    66 add_properties(struct razor_importer *importer,
    67 	       uint32_t type_flags, Header h,
    68 	       int32_t name_tag, int32_t version_tag, int32_t flags_tag)
    69 {
    70 	union rpm_entry names, versions, flags;
    71 	int32_t i, type, count;
    72 
    73 	headerGetEntry(h, name_tag, &type, &names.p, &count);
    74 	headerGetEntry(h, version_tag, &type, &versions.p, &count);
    75 	headerGetEntry(h, flags_tag, &type, &flags.p, &count);
    76 
    77 	for (i = 0; i < count; i++)
    78 		razor_importer_add_property(importer,
    79 					    names.list[i],
    80 					    rpm_to_razor_flags (flags.flags[i]) | type_flags,
    81 					    versions.list[i]);
    82 }
    83 
    84 static void
    85 add_script(struct razor_importer *importer,
    86 	   uint32_t type_flags, Header h,
    87 	   int32_t program_tag, int32_t body_tag)
    88 {
    89 	union rpm_entry program, body;
    90 	int32_t type, count;
    91 
    92 	headerGetEntry(h, program_tag, &type, &program.p, &count);
    93 	headerGetEntry(h, body_tag, &type, &body.p, &count);
    94 
    95 	razor_importer_add_script(importer, type_flags,
    96 				  program.string, body.string);
    97 }
    98 
    99 struct razor_set *
   100 razor_set_create_from_rpmdb(void)
   101 {
   102 	struct razor_importer *importer;
   103 	rpmdbMatchIterator iter;
   104 	Header h;
   105 	int32_t type, count, i;
   106 	union rpm_entry name, epoch, version, release, arch;
   107 	union rpm_entry summary, description, url, license;
   108 	union rpm_entry basenames, dirnames, dirindexes;
   109 	union rpm_entry install_prefixes;
   110 	char filename[PATH_MAX], evr[128], buf[16];
   111 	rpmdb db;
   112 	int imported_count = 0;
   113 
   114 	rpmReadConfigFiles(NULL, NULL);
   115 
   116 	if (rpmdbOpen("", &db, O_RDONLY, 0644) != 0) {
   117 		fprintf(stderr, "cannot open rpm database\n");
   118 		exit(1);
   119 	}
   120 
   121 	importer = razor_importer_create();
   122 
   123 	iter = rpmdbInitIterator(db, 0, NULL, 0);
   124 	while (h = rpmdbNextIterator(iter), h != NULL) {
   125 		headerGetEntry(h, RPMTAG_NAME, &type, &name.p, &count);
   126 		headerGetEntry(h, RPMTAG_EPOCH, &type, &epoch.p, &count);
   127 		headerGetEntry(h, RPMTAG_VERSION, &type, &version.p, &count);
   128 		headerGetEntry(h, RPMTAG_RELEASE, &type, &release.p, &count);
   129 		headerGetEntry(h, RPMTAG_ARCH, &type, &arch.p, &count);
   130 		headerGetEntry(h, RPMTAG_SUMMARY, &type, &summary.p, &count);
   131 		headerGetEntry(h, RPMTAG_DESCRIPTION, &type, &description.p,
   132 			       &count);
   133 		headerGetEntry(h, RPMTAG_URL, &type, &url.p, &count);
   134 		headerGetEntry(h, RPMTAG_LICENSE, &type, &license.p, &count);
   135 
   136 		if (epoch.flags != NULL) {
   137 			snprintf(buf, sizeof buf, "%u", *epoch.flags);
   138 			razor_build_evr(evr, sizeof evr,
   139 					buf, version.string, release.string);
   140 		} else {
   141 			razor_build_evr(evr, sizeof evr,
   142 					NULL, version.string, release.string);
   143 		}
   144 
   145 		razor_importer_begin_package(importer,
   146 					     name.string, evr, arch.string);
   147 		razor_importer_add_details(importer, summary.string,
   148 					   description.string, url.string,
   149 					   license.string);
   150 
   151 		add_properties(importer, RAZOR_PROPERTY_REQUIRES, h,
   152 			       RPMTAG_REQUIRENAME,
   153 			       RPMTAG_REQUIREVERSION,
   154 			       RPMTAG_REQUIREFLAGS);
   155 
   156 		add_properties(importer, RAZOR_PROPERTY_PROVIDES, h,
   157 			       RPMTAG_PROVIDENAME,
   158 			       RPMTAG_PROVIDEVERSION,
   159 			       RPMTAG_PROVIDEFLAGS);
   160 
   161 		add_properties(importer, RAZOR_PROPERTY_OBSOLETES, h,
   162 			       RPMTAG_OBSOLETENAME,
   163 			       RPMTAG_OBSOLETEVERSION,
   164 			       RPMTAG_OBSOLETEFLAGS);
   165 
   166 		add_properties(importer, RAZOR_PROPERTY_CONFLICTS, h,
   167 			       RPMTAG_CONFLICTNAME,
   168 			       RPMTAG_CONFLICTVERSION,
   169 			       RPMTAG_CONFLICTFLAGS);
   170 
   171 		headerGetEntry(h, RPMTAG_BASENAMES, &type,
   172 			       &basenames.p, &count);
   173 		headerGetEntry(h, RPMTAG_DIRNAMES, &type,
   174 			       &dirnames.p, &count);
   175 		headerGetEntry(h, RPMTAG_DIRINDEXES, &type,
   176 			       &dirindexes.p, &count);
   177 		for (i = 0; i < count; i++) {
   178 			snprintf(filename, sizeof filename, "%s%s",
   179 				 dirnames.list[dirindexes.flags[i]],
   180 				 basenames.list[i]);
   181 			razor_importer_add_file(importer, filename);
   182 		}
   183 
   184 		add_script(importer, RAZOR_PROPERTY_PREUN, h,
   185 			   RPMTAG_PREUNPROG, RPMTAG_PREUN);
   186 
   187 		add_script(importer, RAZOR_PROPERTY_POSTUN, h,
   188 			   RPMTAG_POSTUNPROG, RPMTAG_POSTUN);
   189 
   190 		headerGetEntry(h, RPMTAG_INSTPREFIXES, &type,
   191 			       &install_prefixes.p, &count);
   192 		for (i = 0; i < count; i++)
   193 			razor_importer_add_install_prefix(importer,
   194 							  install_prefixes.list[i]);
   195 
   196 		razor_importer_finish_package(importer);
   197 
   198 		printf("\rimporting %d", ++imported_count);
   199 		fflush(stdout);
   200 	}
   201 
   202 	rpmdbClose(db);
   203 
   204 	printf("\nsaving\n");
   205 	return razor_importer_finish(importer);
   206 }