librazor/rpm.c
author Kristian H?gsberg <krh@redhat.com>
Fri Jun 20 23:13:09 2008 -0400 (2008-06-20)
changeset 257 0c3db660514d
parent 247 63444a10fb8e
child 259 5b0601d184ed
permissions -rw-r--r--
When uniquifying properties, also sort them on the owning package.

This ensures that whenever two packages provide or (or require, obsolete
or conflict) the same property, they appear in the same order in the
propertys list of packages.
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
#include <stdio.h>
rhughes@241
    21
#include <stddef.h>
rhughes@241
    22
#include <stdlib.h>
rhughes@241
    23
#include <string.h>
rhughes@241
    24
#include <errno.h>
rhughes@241
    25
#include <sys/stat.h>
rhughes@241
    26
#include <sys/mman.h>
rhughes@241
    27
#include <sys/types.h>
rhughes@241
    28
#include <sys/wait.h>
rhughes@241
    29
#include <fcntl.h>
rhughes@241
    30
#include <dirent.h>
rhughes@241
    31
#include <unistd.h>
rhughes@241
    32
#include <arpa/inet.h>
rhughes@241
    33
#include <zlib.h>
rhughes@241
    34
rhughes@241
    35
#include "razor.h"
rhughes@241
    36
#include "razor-internal.h"
rhughes@241
    37
rhughes@241
    38
#define	RPM_LEAD_SIZE 96
rhughes@241
    39
rhughes@241
    40
enum {
rhughes@241
    41
    PIPE	=  1,	/*!< pipe/fifo */
rhughes@241
    42
    CDEV	=  2,	/*!< character device */
rhughes@241
    43
    XDIR	=  4,	/*!< directory */
rhughes@241
    44
    BDEV	=  6,	/*!< block device */
rhughes@241
    45
    REG		=  8,	/*!< regular file */
rhughes@241
    46
    LINK	= 10,	/*!< hard link */
rhughes@241
    47
    SOCK	= 12	/*!< socket */
rhughes@241
    48
};
rhughes@241
    49
rhughes@241
    50
enum {
krh@247
    51
    RPMSENSE_LESS		= 1 << 1,
krh@247
    52
    RPMSENSE_GREATER		= 1 << 2,
krh@247
    53
    RPMSENSE_EQUAL		= 1 << 3,
krh@247
    54
    RPMSENSE_PREREQ		= 1 << 6,
krh@247
    55
    RPMSENSE_SCRIPT_PRE		= 1 << 9,
krh@247
    56
    RPMSENSE_SCRIPT_POST	= 1 << 10,
krh@247
    57
    RPMSENSE_SCRIPT_PREUN	= 1 << 11,
krh@247
    58
    RPMSENSE_SCRIPT_POSTUN	= 1 << 12,
rhughes@241
    59
};
rhughes@241
    60
rhughes@241
    61
enum {
rhughes@241
    62
    RPMTAG_NAME  		= 1000,	/* s */
rhughes@241
    63
    RPMTAG_VERSION		= 1001,	/* s */
rhughes@241
    64
    RPMTAG_RELEASE		= 1002,	/* s */
rhughes@241
    65
    RPMTAG_EPOCH   		= 1003,	/* i */
rhughes@241
    66
    RPMTAG_SUMMARY		= 1004,	/* s{} */
rhughes@241
    67
    RPMTAG_DESCRIPTION		= 1005,	/* s{} */
rhughes@241
    68
    RPMTAG_BUILDTIME		= 1006,	/* i */
rhughes@241
    69
    RPMTAG_BUILDHOST		= 1007,	/* s */
rhughes@241
    70
    RPMTAG_INSTALLTIME		= 1008,	/* i */
rhughes@241
    71
    RPMTAG_SIZE			= 1009,	/* i */
rhughes@241
    72
    RPMTAG_DISTRIBUTION		= 1010,	/* s */
rhughes@241
    73
    RPMTAG_VENDOR		= 1011,	/* s */
rhughes@241
    74
    RPMTAG_GIF			= 1012,	/* x */
rhughes@241
    75
    RPMTAG_XPM			= 1013,	/* x */
rhughes@241
    76
    RPMTAG_LICENSE		= 1014,	/* s */
rhughes@241
    77
    RPMTAG_PACKAGER		= 1015,	/* s */
rhughes@241
    78
    RPMTAG_GROUP		= 1016,	/* s{} */
rhughes@241
    79
    RPMTAG_CHANGELOG		= 1017, /*!< s[] internal */
rhughes@241
    80
    RPMTAG_SOURCE		= 1018,	/* s[] */
rhughes@241
    81
    RPMTAG_PATCH		= 1019,	/* s[] */
rhughes@241
    82
    RPMTAG_URL			= 1020,	/* s */
rhughes@241
    83
    RPMTAG_OS			= 1021,	/* s legacy used int */
rhughes@241
    84
    RPMTAG_ARCH			= 1022,	/* s legacy used int */
rhughes@241
    85
    RPMTAG_PREIN		= 1023,	/* s */
rhughes@241
    86
    RPMTAG_POSTIN		= 1024,	/* s */
rhughes@241
    87
    RPMTAG_PREUN		= 1025,	/* s */
rhughes@241
    88
    RPMTAG_POSTUN		= 1026,	/* s */
rhughes@241
    89
    RPMTAG_OLDFILENAMES		= 1027, /* s[] obsolete */
rhughes@241
    90
    RPMTAG_FILESIZES		= 1028,	/* i */
rhughes@241
    91
    RPMTAG_FILESTATES		= 1029, /* c */
rhughes@241
    92
    RPMTAG_FILEMODES		= 1030,	/* h */
rhughes@241
    93
    RPMTAG_FILEUIDS		= 1031, /*!< internal */
rhughes@241
    94
    RPMTAG_FILEGIDS		= 1032, /*!< internal */
rhughes@241
    95
    RPMTAG_FILERDEVS		= 1033,	/* h */
rhughes@241
    96
    RPMTAG_FILEMTIMES		= 1034, /* i */
rhughes@241
    97
    RPMTAG_FILEMD5S		= 1035,	/* s[] */
rhughes@241
    98
    RPMTAG_FILELINKTOS		= 1036,	/* s[] */
rhughes@241
    99
    RPMTAG_FILEFLAGS		= 1037,	/* i */
rhughes@241
   100
    RPMTAG_ROOT			= 1038, /*!< internal - obsolete */
rhughes@241
   101
    RPMTAG_FILEUSERNAME		= 1039,	/* s[] */
rhughes@241
   102
    RPMTAG_FILEGROUPNAME	= 1040,	/* s[] */
rhughes@241
   103
    RPMTAG_EXCLUDE		= 1041, /*!< internal - obsolete */
rhughes@241
   104
    RPMTAG_EXCLUSIVE		= 1042, /*!< internal - obsolete */
rhughes@241
   105
    RPMTAG_ICON			= 1043,
rhughes@241
   106
    RPMTAG_SOURCERPM		= 1044,	/* s */
rhughes@241
   107
    RPMTAG_FILEVERIFYFLAGS	= 1045,	/* i */
rhughes@241
   108
    RPMTAG_ARCHIVESIZE		= 1046,	/* i */
rhughes@241
   109
    RPMTAG_PROVIDENAME		= 1047,	/* s[] */
rhughes@241
   110
    RPMTAG_REQUIREFLAGS		= 1048,	/* i */
rhughes@241
   111
    RPMTAG_REQUIRENAME		= 1049,	/* s[] */
rhughes@241
   112
    RPMTAG_REQUIREVERSION	= 1050,	/* s[] */
rhughes@241
   113
    RPMTAG_NOSOURCE		= 1051, /*!< internal */
rhughes@241
   114
    RPMTAG_NOPATCH		= 1052, /*!< internal */
rhughes@241
   115
    RPMTAG_CONFLICTFLAGS	= 1053, /* i */
rhughes@241
   116
    RPMTAG_CONFLICTNAME		= 1054,	/* s[] */
rhughes@241
   117
    RPMTAG_CONFLICTVERSION	= 1055,	/* s[] */
rhughes@241
   118
    RPMTAG_DEFAULTPREFIX	= 1056, /*!< internal - deprecated */
rhughes@241
   119
    RPMTAG_BUILDROOT		= 1057, /*!< internal */
rhughes@241
   120
    RPMTAG_INSTALLPREFIX	= 1058, /*!< internal - deprecated */
rhughes@241
   121
    RPMTAG_EXCLUDEARCH		= 1059,
rhughes@241
   122
    RPMTAG_EXCLUDEOS		= 1060,
rhughes@241
   123
    RPMTAG_EXCLUSIVEARCH	= 1061,
rhughes@241
   124
    RPMTAG_EXCLUSIVEOS		= 1062,
rhughes@241
   125
    RPMTAG_AUTOREQPROV		= 1063, /*!< internal */
rhughes@241
   126
    RPMTAG_RPMVERSION		= 1064,	/* s */
rhughes@241
   127
    RPMTAG_TRIGGERSCRIPTS	= 1065,	/* s[] */
rhughes@241
   128
    RPMTAG_TRIGGERNAME		= 1066,	/* s[] */
rhughes@241
   129
    RPMTAG_TRIGGERVERSION	= 1067,	/* s[] */
rhughes@241
   130
    RPMTAG_TRIGGERFLAGS		= 1068,	/* i */
rhughes@241
   131
    RPMTAG_TRIGGERINDEX		= 1069,	/* i */
rhughes@241
   132
    RPMTAG_VERIFYSCRIPT		= 1079,	/* s */
rhughes@241
   133
    RPMTAG_CHANGELOGTIME	= 1080,	/* i */
rhughes@241
   134
    RPMTAG_CHANGELOGNAME	= 1081,	/* s[] */
rhughes@241
   135
    RPMTAG_CHANGELOGTEXT	= 1082,	/* s[] */
rhughes@241
   136
    RPMTAG_BROKENMD5		= 1083, /*!< internal - obsolete */
rhughes@241
   137
    RPMTAG_PREREQ		= 1084, /*!< internal */
rhughes@241
   138
    RPMTAG_PREINPROG		= 1085,	/* s */
rhughes@241
   139
    RPMTAG_POSTINPROG		= 1086,	/* s */
rhughes@241
   140
    RPMTAG_PREUNPROG		= 1087,	/* s */
rhughes@241
   141
    RPMTAG_POSTUNPROG		= 1088,	/* s */
rhughes@241
   142
    RPMTAG_BUILDARCHS		= 1089,
rhughes@241
   143
    RPMTAG_OBSOLETENAME		= 1090,	/* s[] */
rhughes@241
   144
    RPMTAG_VERIFYSCRIPTPROG	= 1091,	/* s */
rhughes@241
   145
    RPMTAG_TRIGGERSCRIPTPROG	= 1092,	/* s */
rhughes@241
   146
    RPMTAG_DOCDIR		= 1093, /*!< internal */
rhughes@241
   147
    RPMTAG_COOKIE		= 1094,	/* s */
rhughes@241
   148
    RPMTAG_FILEDEVICES		= 1095,	/* i */
rhughes@241
   149
    RPMTAG_FILEINODES		= 1096,	/* i */
rhughes@241
   150
    RPMTAG_FILELANGS		= 1097,	/* s[] */
rhughes@241
   151
    RPMTAG_PREFIXES		= 1098,	/* s[] */
rhughes@241
   152
    RPMTAG_INSTPREFIXES		= 1099,	/* s[] */
rhughes@241
   153
    RPMTAG_TRIGGERIN		= 1100, /*!< internal */
rhughes@241
   154
    RPMTAG_TRIGGERUN		= 1101, /*!< internal */
rhughes@241
   155
    RPMTAG_TRIGGERPOSTUN	= 1102, /*!< internal */
rhughes@241
   156
    RPMTAG_AUTOREQ		= 1103, /*!< internal */
rhughes@241
   157
    RPMTAG_AUTOPROV		= 1104, /*!< internal */
rhughes@241
   158
    RPMTAG_CAPABILITY		= 1105, /*!< internal - obsolete */
rhughes@241
   159
    RPMTAG_SOURCEPACKAGE	= 1106, /*!< i src.rpm header marker */
rhughes@241
   160
    RPMTAG_OLDORIGFILENAMES	= 1107, /*!< internal - obsolete */
rhughes@241
   161
    RPMTAG_BUILDPREREQ		= 1108, /*!< internal */
rhughes@241
   162
    RPMTAG_BUILDREQUIRES	= 1109, /*!< internal */
rhughes@241
   163
    RPMTAG_BUILDCONFLICTS	= 1110, /*!< internal */
rhughes@241
   164
    RPMTAG_BUILDMACROS		= 1111, /*!< internal - unused */
rhughes@241
   165
    RPMTAG_PROVIDEFLAGS		= 1112,	/* i */
rhughes@241
   166
    RPMTAG_PROVIDEVERSION	= 1113,	/* s[] */
rhughes@241
   167
    RPMTAG_OBSOLETEFLAGS	= 1114,	/* i */
rhughes@241
   168
    RPMTAG_OBSOLETEVERSION	= 1115,	/* s[] */
rhughes@241
   169
    RPMTAG_DIRINDEXES		= 1116,	/* i */
rhughes@241
   170
    RPMTAG_BASENAMES		= 1117,	/* s[] */
rhughes@241
   171
    RPMTAG_DIRNAMES		= 1118,	/* s[] */
rhughes@241
   172
    RPMTAG_ORIGDIRINDEXES	= 1119, /*!< internal */
rhughes@241
   173
    RPMTAG_ORIGBASENAMES	= 1120, /*!< internal */
rhughes@241
   174
    RPMTAG_ORIGDIRNAMES		= 1121, /*!< internal */
rhughes@241
   175
    RPMTAG_OPTFLAGS		= 1122,	/* s */
rhughes@241
   176
    RPMTAG_DISTURL		= 1123,	/* s */
rhughes@241
   177
    RPMTAG_PAYLOADFORMAT	= 1124,	/* s */
rhughes@241
   178
    RPMTAG_PAYLOADCOMPRESSOR	= 1125,	/* s */
rhughes@241
   179
    RPMTAG_PAYLOADFLAGS		= 1126,	/* s */
rhughes@241
   180
    RPMTAG_INSTALLCOLOR		= 1127, /*!< i transaction color when installed */
rhughes@241
   181
    RPMTAG_INSTALLTID		= 1128,	/* i */
rhughes@241
   182
    RPMTAG_REMOVETID		= 1129,	/* i */
rhughes@241
   183
    RPMTAG_SHA1RHN		= 1130, /*!< internal - obsolete */
rhughes@241
   184
    RPMTAG_RHNPLATFORM		= 1131,	/* s */
rhughes@241
   185
    RPMTAG_PLATFORM		= 1132,	/* s */
rhughes@241
   186
    RPMTAG_PATCHESNAME		= 1133, /*!< placeholder (SuSE) */
rhughes@241
   187
    RPMTAG_PATCHESFLAGS		= 1134, /*!< placeholder (SuSE) */
rhughes@241
   188
    RPMTAG_PATCHESVERSION	= 1135, /*!< placeholder (SuSE) */
rhughes@241
   189
    RPMTAG_CACHECTIME		= 1136,	/* i */
rhughes@241
   190
    RPMTAG_CACHEPKGPATH		= 1137,	/* s */
rhughes@241
   191
    RPMTAG_CACHEPKGSIZE		= 1138,	/* i */
rhughes@241
   192
    RPMTAG_CACHEPKGMTIME	= 1139,	/* i */
rhughes@241
   193
    RPMTAG_FILECOLORS		= 1140,	/* i */
rhughes@241
   194
    RPMTAG_FILECLASS		= 1141,	/* i */
rhughes@241
   195
    RPMTAG_CLASSDICT		= 1142,	/* s[] */
rhughes@241
   196
    RPMTAG_FILEDEPENDSX		= 1143,	/* i */
rhughes@241
   197
    RPMTAG_FILEDEPENDSN		= 1144,	/* i */
rhughes@241
   198
    RPMTAG_DEPENDSDICT		= 1145,	/* i */
rhughes@241
   199
    RPMTAG_SOURCEPKGID		= 1146,	/* x */
rhughes@241
   200
    RPMTAG_FILECONTEXTS		= 1147,	/* s[] */
rhughes@241
   201
    RPMTAG_FSCONTEXTS		= 1148,	/*!< s[] extension */
rhughes@241
   202
    RPMTAG_RECONTEXTS		= 1149,	/*!< s[] extension */
rhughes@241
   203
    RPMTAG_POLICIES		= 1150,	/*!< s[] selinux *.te policy file. */
rhughes@241
   204
    RPMTAG_PRETRANS		= 1151,	/* s */
rhughes@241
   205
    RPMTAG_POSTTRANS		= 1152,	/* s */
rhughes@241
   206
    RPMTAG_PRETRANSPROG		= 1153,	/* s */
rhughes@241
   207
    RPMTAG_POSTTRANSPROG	= 1154,	/* s */
rhughes@241
   208
    RPMTAG_DISTTAG		= 1155,	/* s */
rhughes@241
   209
    RPMTAG_SUGGESTSNAME		= 1156,	/* s[] extension placeholder */
rhughes@241
   210
    RPMTAG_SUGGESTSVERSION	= 1157,	/* s[] extension placeholder */
rhughes@241
   211
    RPMTAG_SUGGESTSFLAGS	= 1158,	/* i   extension placeholder */
rhughes@241
   212
    RPMTAG_ENHANCESNAME		= 1159,	/* s[] extension placeholder */
rhughes@241
   213
    RPMTAG_ENHANCESVERSION	= 1160,	/* s[] extension placeholder */
rhughes@241
   214
    RPMTAG_ENHANCESFLAGS	= 1161,	/* i   extension placeholder */
rhughes@241
   215
    RPMTAG_PRIORITY		= 1162, /* i   extension placeholder */
rhughes@241
   216
    RPMTAG_CVSID		= 1163, /* s */
rhughes@241
   217
    RPMTAG_TRIGGERPREIN		= 1171, /*!< internal */
rhughes@241
   218
};
rhughes@241
   219
rhughes@241
   220
struct rpm_header {
rhughes@241
   221
	unsigned char magic[4];
rhughes@241
   222
	unsigned char reserved[4];
rhughes@241
   223
	int nindex;
rhughes@241
   224
	int hsize;
rhughes@241
   225
};
rhughes@241
   226
rhughes@241
   227
struct rpm_header_index {
rhughes@241
   228
	int tag;
rhughes@241
   229
	int type;
rhughes@241
   230
	int offset;
rhughes@241
   231
	int count;
rhughes@241
   232
};
rhughes@241
   233
rhughes@241
   234
struct razor_rpm {
rhughes@241
   235
	struct rpm_header *signature;
rhughes@241
   236
	struct rpm_header *header;
rhughes@241
   237
	const char **dirs;
rhughes@241
   238
	const char *pool;
rhughes@241
   239
	void *map;
rhughes@241
   240
	size_t size;
rhughes@241
   241
	void *payload;
rhughes@241
   242
};
rhughes@241
   243
rhughes@241
   244
static struct rpm_header_index *
rhughes@241
   245
razor_rpm_get_header(struct razor_rpm *rpm, unsigned int tag)
rhughes@241
   246
{
rhughes@241
   247
	struct rpm_header_index *index, *end;
rhughes@241
   248
rhughes@241
   249
	index = (struct rpm_header_index *) (rpm->header + 1);
rhughes@241
   250
	end = index + ntohl(rpm->header->nindex);
rhughes@241
   251
	while (index < end) {
rhughes@241
   252
		if (ntohl(index->tag) == tag)
rhughes@241
   253
			return index;
rhughes@241
   254
		index++;
rhughes@241
   255
	}
rhughes@241
   256
rhughes@241
   257
	return NULL;
rhughes@241
   258
}
rhughes@241
   259
rhughes@241
   260
static const void *
rhughes@241
   261
razor_rpm_get_indirect(struct razor_rpm *rpm,
rhughes@241
   262
		       unsigned int tag, unsigned int *count)
rhughes@241
   263
{
rhughes@241
   264
	struct rpm_header_index *index;
rhughes@241
   265
rhughes@241
   266
	index = razor_rpm_get_header(rpm, tag);
rhughes@241
   267
	if (index != NULL) {
rhughes@241
   268
		if (count)
rhughes@241
   269
			*count = ntohl(index->count);
rhughes@241
   270
rhughes@241
   271
		return rpm->pool + ntohl(index->offset);
rhughes@241
   272
	}
rhughes@241
   273
rhughes@241
   274
	return NULL;
rhughes@241
   275
}
rhughes@241
   276
krh@247
   277
static uint32_t
rhughes@241
   278
rpm_to_razor_flags(uint32_t flags)
rhughes@241
   279
{
krh@247
   280
	uint32_t razor_flags;
rhughes@241
   281
krh@247
   282
	razor_flags = 0;
krh@247
   283
	if (flags & RPMSENSE_LESS)
krh@247
   284
		razor_flags |= RAZOR_PROPERTY_LESS;
krh@247
   285
	if (flags & RPMSENSE_EQUAL)
krh@247
   286
		razor_flags |= RAZOR_PROPERTY_EQUAL;
krh@247
   287
	if (flags & RPMSENSE_GREATER)
krh@247
   288
		razor_flags |= RAZOR_PROPERTY_GREATER;
krh@247
   289
krh@247
   290
	if (flags & RPMSENSE_SCRIPT_PRE)
krh@247
   291
		razor_flags |= RAZOR_PROPERTY_PRE;
krh@247
   292
	if (flags & RPMSENSE_SCRIPT_POST)
krh@247
   293
		razor_flags |= RAZOR_PROPERTY_POST;
krh@247
   294
	if (flags & RPMSENSE_SCRIPT_PREUN)
krh@247
   295
		razor_flags |= RAZOR_PROPERTY_PREUN;
krh@247
   296
	if (flags & RPMSENSE_SCRIPT_POSTUN)
krh@247
   297
		razor_flags |= RAZOR_PROPERTY_POSTUN;
krh@247
   298
	
krh@247
   299
	return razor_flags;
rhughes@241
   300
}
rhughes@241
   301
rhughes@241
   302
static void
krh@247
   303
import_properties(struct razor_importer *importer, uint32_t type,
rhughes@241
   304
		  struct razor_rpm *rpm,
rhughes@241
   305
		  int name_tag, int version_tag, int flags_tag)
rhughes@241
   306
{
rhughes@241
   307
	const char *name, *version;
rhughes@241
   308
	const uint32_t *flags;
rhughes@241
   309
	uint32_t f;
rhughes@241
   310
	unsigned int i, count;
rhughes@241
   311
rhughes@241
   312
	name = razor_rpm_get_indirect(rpm, name_tag, &count);
rhughes@241
   313
	if (name == NULL)
rhughes@241
   314
		return;
rhughes@241
   315
rhughes@241
   316
	flags = razor_rpm_get_indirect(rpm, flags_tag, &count);
rhughes@241
   317
rhughes@241
   318
	version = razor_rpm_get_indirect(rpm, version_tag, &count);
rhughes@241
   319
	for (i = 0; i < count; i++) {
rhughes@241
   320
		f = rpm_to_razor_flags(ntohl(flags[i]));
krh@247
   321
		razor_importer_add_property(importer, name, f | type, version);
rhughes@241
   322
		name += strlen(name) + 1;
rhughes@241
   323
		version += strlen(version) + 1;
rhughes@241
   324
	}
rhughes@241
   325
}
rhughes@241
   326
rhughes@241
   327
static void
rhughes@241
   328
import_files(struct razor_importer *importer, struct razor_rpm *rpm)
rhughes@241
   329
{
rhughes@241
   330
	const char *name;
rhughes@241
   331
	const uint32_t *index;
rhughes@241
   332
	unsigned int i, count;
rhughes@241
   333
	char buffer[256];
rhughes@241
   334
krh@246
   335
	if (rpm->dirs == NULL)
krh@246
   336
		return;
krh@246
   337
rhughes@241
   338
	/* assert: count is the same for all arrays */
rhughes@241
   339
	index = razor_rpm_get_indirect(rpm, RPMTAG_DIRINDEXES, &count);
rhughes@241
   340
	name = razor_rpm_get_indirect(rpm, RPMTAG_BASENAMES, &count);
rhughes@241
   341
	for (i = 0; i < count; i++) {
rhughes@241
   342
		snprintf(buffer, sizeof buffer,
rhughes@241
   343
			 "%s%s", rpm->dirs[ntohl(*index)], name);
rhughes@241
   344
		razor_importer_add_file(importer, buffer);
rhughes@241
   345
		name += strlen(name) + 1;
rhughes@241
   346
		index++;
rhughes@241
   347
	}
rhughes@241
   348
}
rhughes@241
   349
rhughes@241
   350
struct razor_rpm *
rhughes@241
   351
razor_rpm_open(const char *filename)
rhughes@241
   352
{
rhughes@241
   353
	struct razor_rpm *rpm;
rhughes@241
   354
	struct rpm_header_index *base, *index;
rhughes@241
   355
	struct stat buf;
rhughes@241
   356
	unsigned int count, i, nindex, hsize;
rhughes@241
   357
	const char *name;
rhughes@241
   358
	int fd;
rhughes@241
   359
rhughes@241
   360
	rpm = malloc(sizeof *rpm);
krh@246
   361
	if (rpm == NULL)
krh@246
   362
		return NULL;
rhughes@241
   363
	memset(rpm, 0, sizeof *rpm);
rhughes@241
   364
rhughes@241
   365
	fd = open(filename, O_RDONLY);
rhughes@241
   366
	if (fd < 0) {
rhughes@241
   367
		fprintf(stderr, "couldn't open %s\n", filename);
rhughes@241
   368
		return NULL;
rhughes@241
   369
	}
rhughes@241
   370
rhughes@241
   371
	if (fstat(fd, &buf) < 0) {
rhughes@241
   372
		fprintf(stderr, "failed to stat %s (%m)\n", filename);
rhughes@241
   373
		return NULL;
rhughes@241
   374
	}
rhughes@241
   375
rhughes@241
   376
	rpm->size = buf.st_size;
rhughes@241
   377
	rpm->map = mmap(NULL, rpm->size, PROT_READ, MAP_PRIVATE, fd, 0);
rhughes@241
   378
	if (rpm->map == MAP_FAILED) {
rhughes@241
   379
		fprintf(stderr, "couldn't mmap %s\n", filename);
rhughes@241
   380
		return NULL;
rhughes@241
   381
	}
rhughes@241
   382
	close(fd);
rhughes@241
   383
rhughes@241
   384
	rpm->signature = rpm->map + RPM_LEAD_SIZE;
rhughes@241
   385
	nindex = ntohl(rpm->signature->nindex);
rhughes@241
   386
	hsize = ntohl(rpm->signature->hsize);
rhughes@241
   387
	rpm->header = (void *) (rpm->signature + 1) +
rhughes@241
   388
		ALIGN(nindex * sizeof *index + hsize, 8);
rhughes@241
   389
	nindex = ntohl(rpm->header->nindex);
rhughes@241
   390
	hsize = ntohl(rpm->header->hsize);
rhughes@241
   391
	rpm->payload = (void *) (rpm->header + 1) +
rhughes@241
   392
		nindex * sizeof *index + hsize;
rhughes@241
   393
rhughes@241
   394
	base = (struct rpm_header_index *) (rpm->header + 1);
rhughes@241
   395
	rpm->pool = (void *) base + nindex * sizeof *index;
rhughes@241
   396
rhughes@241
   397
	/* Look up dir names now so we can index them directly. */
rhughes@241
   398
	name = razor_rpm_get_indirect(rpm, RPMTAG_DIRNAMES, &count);
rhughes@241
   399
	if (name) {
rhughes@241
   400
		rpm->dirs = calloc(count, sizeof *rpm->dirs);
rhughes@241
   401
		for (i = 0; i < count; i++) {
rhughes@241
   402
			rpm->dirs[i] = name;
rhughes@241
   403
			name += strlen(name) + 1;
rhughes@241
   404
		}
rhughes@241
   405
	} else {
rhughes@241
   406
		name = razor_rpm_get_indirect(rpm, RPMTAG_OLDFILENAMES,
rhughes@241
   407
					      &count);
rhughes@241
   408
		if (name) {
rhughes@241
   409
			fprintf(stderr, "old filenames not supported\n");
rhughes@241
   410
			return NULL;
rhughes@241
   411
		}
rhughes@241
   412
	}
rhughes@241
   413
rhughes@241
   414
	return rpm;
rhughes@241
   415
}
rhughes@241
   416
rhughes@241
   417
struct cpio_file_header {
rhughes@241
   418
	char magic[6];
rhughes@241
   419
	char inode[8];
rhughes@241
   420
	char mode[8];
rhughes@241
   421
	char uid[8];
rhughes@241
   422
	char gid[8];
rhughes@241
   423
	char nlink[8];
rhughes@241
   424
	char mtime[8];
rhughes@241
   425
	char filesize[8];
rhughes@241
   426
	char devmajor[8];
rhughes@241
   427
	char devminor[8];
rhughes@241
   428
	char rdevmajor[8];
rhughes@241
   429
	char rdevminor[8];
rhughes@241
   430
	char namesize[8];
rhughes@241
   431
	char checksum[8];
rhughes@241
   432
	char filename[0];
rhughes@241
   433
};
rhughes@241
   434
rhughes@241
   435
/* gzip flags */
rhughes@241
   436
#define ASCII_FLAG   0x01 /* bit 0 set: file probably ascii text */
rhughes@241
   437
#define HEAD_CRC     0x02 /* bit 1 set: header CRC present */
rhughes@241
   438
#define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
rhughes@241
   439
#define ORIG_NAME    0x08 /* bit 3 set: original file name present */
rhughes@241
   440
#define COMMENT      0x10 /* bit 4 set: file comment present */
rhughes@241
   441
#define RESERVED     0xE0 /* bits 5..7: reserved */
rhughes@241
   442
rhughes@241
   443
struct installer {
rhughes@241
   444
	const char *root;
rhughes@241
   445
	struct razor_rpm *rpm;
rhughes@241
   446
	z_stream stream;
rhughes@241
   447
	unsigned char buffer[32768];
rhughes@241
   448
	size_t rest, length;
rhughes@241
   449
};
rhughes@241
   450
rhughes@241
   451
static int
rhughes@241
   452
installer_inflate(struct installer *installer)
rhughes@241
   453
{
rhughes@241
   454
	size_t length;
rhughes@241
   455
	int err;
rhughes@241
   456
rhughes@241
   457
	if (installer->rest > sizeof installer->buffer)
rhughes@241
   458
		length = sizeof installer->buffer;
rhughes@241
   459
	else
rhughes@241
   460
		length = installer->rest;
rhughes@241
   461
rhughes@241
   462
	installer->stream.next_out = installer->buffer;
rhughes@241
   463
	installer->stream.avail_out = length;
rhughes@241
   464
	err = inflate(&installer->stream, Z_SYNC_FLUSH);
rhughes@241
   465
	if (err != Z_OK && err != Z_STREAM_END) {
rhughes@241
   466
		fprintf(stderr, "inflate error: %d (%m)\n", err);
rhughes@241
   467
		return -1;
rhughes@241
   468
	}
rhughes@241
   469
rhughes@241
   470
	installer->rest -= length;
rhughes@241
   471
	installer->length = length;
rhughes@241
   472
rhughes@241
   473
	return 0;
rhughes@241
   474
}
rhughes@241
   475
rhughes@241
   476
static int
rhughes@241
   477
installer_align(struct installer *installer, size_t size)
rhughes@241
   478
{
rhughes@241
   479
	unsigned char buffer[4];
rhughes@241
   480
	int err;
rhughes@241
   481
rhughes@241
   482
	installer->stream.next_out = buffer;
rhughes@241
   483
	installer->stream.avail_out =
rhughes@241
   484
		(size - installer->stream.total_out) & (size - 1);
rhughes@241
   485
rhughes@241
   486
	if (installer->stream.avail_out == 0)
rhughes@241
   487
		return 0;
rhughes@241
   488
rhughes@241
   489
	err = inflate(&installer->stream, Z_SYNC_FLUSH);
rhughes@241
   490
	if (err != Z_OK && err != Z_STREAM_END) {
rhughes@241
   491
		fprintf(stderr, "inflate error: %d (%m)\n", err);
rhughes@241
   492
		return -1;
rhughes@241
   493
	}
rhughes@241
   494
rhughes@241
   495
	return 0;
rhughes@241
   496
}
rhughes@241
   497
rhughes@241
   498
static int
rhughes@241
   499
create_path(struct installer *installer, const char *path, unsigned int mode)
rhughes@241
   500
{
rhughes@241
   501
	char buffer[PATH_MAX];
rhughes@241
   502
	struct stat buf;
rhughes@241
   503
	int fd, ret;
rhughes@241
   504
rhughes@241
   505
	if (razor_create_dir(installer->root, path) < 0)
rhughes@241
   506
		return -1;
rhughes@241
   507
rhughes@241
   508
	snprintf(buffer, sizeof buffer, "%s%s", installer->root, path);
rhughes@241
   509
rhughes@241
   510
	switch (mode >> 12) {
rhughes@241
   511
	case REG:
rhughes@241
   512
		/* FIXME: handle the case where a file is already there. */
rhughes@241
   513
		fd = open(buffer, O_WRONLY | O_CREAT | O_TRUNC, mode & 0x1ff);
rhughes@241
   514
		if (fd < 0){
rhughes@241
   515
			fprintf(stderr, "failed to create file %s\n", buffer);
rhughes@241
   516
			return -1;
rhughes@241
   517
		}
rhughes@241
   518
		while (installer->rest > 0) {
rhughes@241
   519
			if (installer_inflate(installer)) {
rhughes@241
   520
				fprintf(stderr, "failed to inflate\n");
rhughes@241
   521
				return -1;
rhughes@241
   522
			}
rhughes@241
   523
			if (razor_write(fd, installer->buffer,
rhughes@241
   524
					installer->length)) {
rhughes@241
   525
				fprintf(stderr, "failed to write payload\n");
rhughes@241
   526
				return -1;
rhughes@241
   527
			}
rhughes@241
   528
		}
rhughes@241
   529
		if (close(fd) < 0) {
rhughes@241
   530
			fprintf(stderr, "failed to close %s: %m\n", buffer);
rhughes@241
   531
			return -1;
rhughes@241
   532
		}
rhughes@241
   533
		return 0;
rhughes@241
   534
	case XDIR:
rhughes@241
   535
		ret = mkdir(buffer, mode & 0x1ff);
rhughes@241
   536
		if (ret == 0 || errno != EEXIST)
rhughes@241
   537
			return ret;
rhughes@241
   538
		if (stat(buffer, &buf) || !S_ISDIR(buf.st_mode)) {
rhughes@241
   539
			/* FIXME: also check that mode match. */
rhughes@241
   540
			fprintf(stderr,
rhughes@241
   541
				"%s exists but is not a directory\n", buffer);
rhughes@241
   542
			return -1;
rhughes@241
   543
		}
rhughes@241
   544
		return 0;
rhughes@241
   545
	case PIPE:
rhughes@241
   546
	case CDEV:
rhughes@241
   547
	case BDEV:
rhughes@241
   548
	case SOCK:
rhughes@241
   549
		printf("%s: unhandled file type %d\n", buffer, mode >> 12);
rhughes@241
   550
		return 0;
rhughes@241
   551
	case LINK:
rhughes@241
   552
		if (installer_inflate(installer)) {
rhughes@241
   553
			fprintf(stderr, "failed to inflate\n");
rhughes@241
   554
			return -1;
rhughes@241
   555
		}
rhughes@241
   556
		if (installer->length >= sizeof installer->buffer) {
rhughes@241
   557
			fprintf(stderr, "link name too long\n");
rhughes@241
   558
			return -1;
rhughes@241
   559
		}
rhughes@241
   560
		installer->buffer[installer->length] = '\0';
rhughes@241
   561
		if (symlink((const char *) installer->buffer, buffer)) {
rhughes@241
   562
			fprintf(stderr, "failed to create symlink, %m\n");
rhughes@241
   563
			return -1;
rhughes@241
   564
		}
rhughes@241
   565
		return 0;
rhughes@241
   566
	default:
rhughes@241
   567
		printf("%s: unknown file type %d\n", buffer, mode >> 12);
rhughes@241
   568
		return 0;
rhughes@241
   569
	}
rhughes@241
   570
}
rhughes@241
   571
rhughes@241
   572
static int
rhughes@241
   573
run_script(struct installer *installer,
rhughes@241
   574
	   unsigned int program_tag, unsigned int script_tag)
rhughes@241
   575
{
rhughes@241
   576
	int pid, status, fd[2];
rhughes@241
   577
	const char *script = NULL, *program = NULL;
rhughes@241
   578
rhughes@241
   579
	program = razor_rpm_get_indirect(installer->rpm, program_tag, NULL);
rhughes@241
   580
	script = razor_rpm_get_indirect(installer->rpm, script_tag, NULL);
rhughes@241
   581
	if (program == NULL && script == NULL) {
rhughes@241
   582
		return 0;
rhughes@241
   583
	} else if (program == NULL) {
rhughes@241
   584
		program = "/bin/sh";
rhughes@241
   585
	}
rhughes@241
   586
rhughes@241
   587
	if (pipe(fd) < 0) {
rhughes@241
   588
		fprintf(stderr, "failed to create pipe\n");
rhughes@241
   589
		return -1;
rhughes@241
   590
	}
rhughes@241
   591
	pid = fork();
rhughes@241
   592
	if (pid < 0) {
rhughes@241
   593
		fprintf(stderr, "failed to fork, %m\n");
rhughes@241
   594
	} else if (pid == 0) {
rhughes@241
   595
		if (dup2(fd[0], STDIN_FILENO) < 0) {
rhughes@241
   596
			fprintf(stderr, "failed redirect stdin, %m\n");
krh@256
   597
			exit(-1);
rhughes@241
   598
		}
rhughes@241
   599
		if (close(fd[0]) < 0 || close(fd[1]) < 0) {
rhughes@241
   600
			fprintf(stderr, "failed to close pipe, %m\n");
krh@256
   601
			exit(-1);
rhughes@241
   602
		}
rhughes@241
   603
		if (chroot(installer->root) < 0) {
rhughes@241
   604
			fprintf(stderr, "failed to chroot to %s, %m\n",
rhughes@241
   605
				installer->root);
krh@256
   606
			exit(-1);
rhughes@241
   607
		}
rhughes@241
   608
		printf("executing program %s in chroot %s\n",
rhughes@241
   609
		       program, installer->root);
rhughes@241
   610
		if (execl(program, program, NULL)) {
rhughes@241
   611
			fprintf(stderr, "failed to exec %s, %m\n", program);
rhughes@241
   612
			exit(-1);
rhughes@241
   613
		}
rhughes@241
   614
	} else {
rhughes@241
   615
		if (script && razor_write(fd[1], script, strlen(script)) < 0) {
rhughes@241
   616
			fprintf(stderr, "failed to pipe script, %m\n");
rhughes@241
   617
			return -1;
rhughes@241
   618
		}
rhughes@241
   619
		if (close(fd[0]) || close(fd[1])) {
rhughes@241
   620
			fprintf(stderr, "failed to close pipe, %m\n");
rhughes@241
   621
			return -1;
rhughes@241
   622
		}
rhughes@241
   623
		if (wait(&status) < 0) {
rhughes@241
   624
			fprintf(stderr, "wait for child failed, %m");
rhughes@241
   625
			return -1;
rhughes@241
   626
		}
rhughes@241
   627
		if (status)
rhughes@241
   628
			printf("script exited with status %d\n", status);
rhughes@241
   629
	}
rhughes@241
   630
rhughes@241
   631
	return 0;
rhughes@241
   632
}
rhughes@241
   633
rhughes@241
   634
static int
rhughes@241
   635
installer_init(struct installer *installer)
rhughes@241
   636
{
rhughes@241
   637
	unsigned char *gz_header;
rhughes@241
   638
	int method, flags, err;
rhughes@241
   639
rhughes@241
   640
	gz_header = installer->rpm->payload;
rhughes@241
   641
	if (gz_header[0] != 0x1f || gz_header[1] != 0x8b) {
rhughes@241
   642
		fprintf(stderr, "payload section doesn't have gz header\n");
rhughes@241
   643
		return -1;
rhughes@241
   644
	}
rhughes@241
   645
rhughes@241
   646
	method = gz_header[2];
rhughes@241
   647
	flags = gz_header[3];
rhughes@241
   648
rhughes@241
   649
	if (method != Z_DEFLATED || flags != 0) {
rhughes@241
   650
		fprintf(stderr,
rhughes@241
   651
			"unknown payload compression method or flags set\n");
rhughes@241
   652
		return -1;
rhughes@241
   653
	}
rhughes@241
   654
rhughes@241
   655
	installer->stream.zalloc = NULL;
rhughes@241
   656
	installer->stream.zfree = NULL;
rhughes@241
   657
	installer->stream.opaque = NULL;
rhughes@241
   658
rhughes@241
   659
	installer->stream.next_in  = gz_header + 10;
rhughes@241
   660
	installer->stream.avail_in =
rhughes@241
   661
		(installer->rpm->map + installer->rpm->size) -
rhughes@241
   662
		(void *) installer->stream.next_in;
rhughes@241
   663
	installer->stream.next_out = NULL;
rhughes@241
   664
	installer->stream.avail_out = 0;
rhughes@241
   665
rhughes@241
   666
	err = inflateInit2(&installer->stream, -MAX_WBITS);
rhughes@241
   667
	if (err != Z_OK) {
rhughes@241
   668
		fprintf(stderr, "inflateInit error: %d\n", err);
rhughes@241
   669
		return -1;
rhughes@241
   670
	}
rhughes@241
   671
rhughes@241
   672
	return 0;
rhughes@241
   673
}
rhughes@241
   674
rhughes@241
   675
static int
rhughes@241
   676
installer_finish(struct installer *installer)
rhughes@241
   677
{
rhughes@241
   678
	int err;
rhughes@241
   679
rhughes@241
   680
	err = inflateEnd(&installer->stream);
rhughes@241
   681
rhughes@241
   682
	if (err != Z_OK) {
rhughes@241
   683
		fprintf(stderr, "inflateEnd error: %d\n", err);
rhughes@241
   684
		return -1;
rhughes@241
   685
	}
rhughes@241
   686
rhughes@241
   687
	return 0;
rhughes@241
   688
}
rhughes@241
   689
rhughes@241
   690
static unsigned long
rhughes@241
   691
fixed_hex_to_ulong(const char *hex, int length)
rhughes@241
   692
{
rhughes@241
   693
	long l;
rhughes@241
   694
	int i;
rhughes@241
   695
rhughes@241
   696
	for (i = 0, l = 0; i < length; i++) {
rhughes@241
   697
		if (hex[i] < 'a')
rhughes@241
   698
			l = l * 16 + hex[i] - '0';
rhughes@241
   699
		else
rhughes@241
   700
			l = l * 16 + hex[i] - 'a' + 10;
rhughes@241
   701
	}
rhughes@241
   702
rhughes@241
   703
	return l;
rhughes@241
   704
}
rhughes@241
   705
rhughes@241
   706
int
rhughes@241
   707
razor_rpm_install(struct razor_rpm *rpm, const char *root)
rhughes@241
   708
{
rhughes@241
   709
	struct installer installer;
rhughes@241
   710
	struct cpio_file_header *header;
rhughes@241
   711
	struct stat buf;
rhughes@241
   712
	unsigned int mode;
rhughes@241
   713
	char *path;
rhughes@241
   714
	size_t filesize;
rhughes@241
   715
rhughes@241
   716
	installer.rpm = rpm;
rhughes@241
   717
	installer.root = root;
rhughes@241
   718
rhughes@241
   719
	/* FIXME: Only do this before a transaction, not per rpm. */
rhughes@241
   720
	if (stat(root, &buf) < 0 || !S_ISDIR(buf.st_mode)) {
rhughes@241
   721
		fprintf(stderr,
rhughes@241
   722
			"root installation directory \"%s\" does not exist\n",
rhughes@241
   723
			root);
rhughes@241
   724
		return -1;
rhughes@241
   725
	}
rhughes@241
   726
rhughes@241
   727
	if (installer_init(&installer))
rhughes@241
   728
		return -1;
rhughes@241
   729
rhughes@241
   730
	run_script(&installer, RPMTAG_PREINPROG, RPMTAG_PREIN);
rhughes@241
   731
rhughes@241
   732
	while (installer.stream.avail_in > 0) {
rhughes@241
   733
		installer.rest = sizeof *header;
rhughes@241
   734
		if (installer_inflate(&installer))
rhughes@241
   735
			return -1;
rhughes@241
   736
rhughes@241
   737
		header = (struct cpio_file_header *) installer.buffer;
rhughes@241
   738
		mode = fixed_hex_to_ulong(header->mode, sizeof header->mode);
rhughes@241
   739
		filesize = fixed_hex_to_ulong(header->filesize,
rhughes@241
   740
					      sizeof header->filesize);
rhughes@241
   741
rhughes@241
   742
		installer.rest = fixed_hex_to_ulong(header->namesize,
rhughes@241
   743
						    sizeof header->namesize);
rhughes@241
   744
rhughes@241
   745
		if (installer_inflate(&installer) ||
rhughes@241
   746
		    installer_align(&installer, 4))
rhughes@241
   747
			return -1;
rhughes@241
   748
rhughes@241
   749
		path = (char *) installer.buffer;
rhughes@241
   750
		/* This convention is so lame... */
rhughes@241
   751
		if (strcmp(path, "TRAILER!!!") == 0)
rhughes@241
   752
			break;
rhughes@241
   753
rhughes@241
   754
		installer.rest = filesize;
rhughes@241
   755
		if (create_path(&installer, path + 1, mode) < 0)
rhughes@241
   756
			return -1;
rhughes@241
   757
		if (installer_align(&installer, 4))
rhughes@241
   758
			return -1;
rhughes@241
   759
	}
rhughes@241
   760
rhughes@241
   761
	if (installer_finish(&installer))
rhughes@241
   762
		return -1;
rhughes@241
   763
rhughes@241
   764
	run_script(&installer, RPMTAG_POSTINPROG, RPMTAG_POSTIN);
rhughes@241
   765
rhughes@241
   766
	return 0;
rhughes@241
   767
}
rhughes@241
   768
rhughes@241
   769
int
rhughes@241
   770
razor_rpm_close(struct razor_rpm *rpm)
rhughes@241
   771
{
rhughes@241
   772
	int err;
rhughes@241
   773
rhughes@241
   774
	free(rpm->dirs);
rhughes@241
   775
	err = munmap(rpm->map, rpm->size);
rhughes@241
   776
	free(rpm);
rhughes@241
   777
rhughes@241
   778
	return err;
rhughes@241
   779
}
rhughes@241
   780
rhughes@241
   781
int
rhughes@241
   782
razor_importer_add_rpm(struct razor_importer *importer, struct razor_rpm *rpm)
rhughes@241
   783
{
rhughes@241
   784
	const char *name, *version, *release, *arch;
rhughes@241
   785
	const uint32_t *epoch;
rhughes@241
   786
	char evr[128], buf[16];
rhughes@241
   787
rhughes@241
   788
	name = razor_rpm_get_indirect(rpm, RPMTAG_NAME, NULL);
rhughes@241
   789
	epoch = razor_rpm_get_indirect(rpm, RPMTAG_EPOCH, NULL);
rhughes@241
   790
	version = razor_rpm_get_indirect(rpm, RPMTAG_VERSION, NULL);
rhughes@241
   791
	release = razor_rpm_get_indirect(rpm, RPMTAG_RELEASE, NULL);
rhughes@241
   792
	arch = razor_rpm_get_indirect(rpm, RPMTAG_ARCH, NULL);
rhughes@241
   793
rhughes@241
   794
	if (epoch) {
rhughes@241
   795
		snprintf(buf, sizeof buf, "%u", ntohl(*epoch));
rhughes@241
   796
		razor_build_evr(evr, sizeof evr, buf, version, release);
rhughes@241
   797
	} else {
rhughes@241
   798
		razor_build_evr(evr, sizeof evr, NULL, version, release);
rhughes@241
   799
	}
rhughes@241
   800
	razor_importer_begin_package(importer, name, evr, arch);
rhughes@241
   801
rhughes@241
   802
	import_properties(importer, RAZOR_PROPERTY_REQUIRES, rpm,
rhughes@241
   803
			  RPMTAG_REQUIRENAME,
rhughes@241
   804
			  RPMTAG_REQUIREVERSION,
rhughes@241
   805
			  RPMTAG_REQUIREFLAGS);
rhughes@241
   806
rhughes@241
   807
	import_properties(importer, RAZOR_PROPERTY_PROVIDES, rpm,
rhughes@241
   808
			  RPMTAG_PROVIDENAME,
rhughes@241
   809
			  RPMTAG_PROVIDEVERSION,
rhughes@241
   810
			  RPMTAG_PROVIDEFLAGS);
rhughes@241
   811
rhughes@241
   812
	import_properties(importer, RAZOR_PROPERTY_OBSOLETES, rpm,
rhughes@241
   813
			  RPMTAG_OBSOLETENAME,
rhughes@241
   814
			  RPMTAG_OBSOLETEVERSION,
rhughes@241
   815
			  RPMTAG_OBSOLETEFLAGS);
rhughes@241
   816
rhughes@241
   817
	import_properties(importer, RAZOR_PROPERTY_CONFLICTS, rpm,
rhughes@241
   818
			  RPMTAG_CONFLICTNAME,
rhughes@241
   819
			  RPMTAG_CONFLICTVERSION,
rhughes@241
   820
			  RPMTAG_CONFLICTFLAGS);
rhughes@241
   821
rhughes@241
   822
	import_files(importer, rpm);
rhughes@241
   823
rhughes@241
   824
	razor_importer_finish_package(importer);
rhughes@241
   825
rhughes@241
   826
	return 0;
rhughes@241
   827
}