librazor/rpm.c
author James Bowes <jbowes@redhat.com>
Wed Jul 09 10:11:13 2008 -0400 (2008-07-09)
changeset 318 829d6711b316
parent 289 dc69c55cf462
child 322 66c281524c98
permissions -rw-r--r--
Use strings to identify section types in the on-disk repo format.

Previously, a given razor file type had a fixed number of sections in a
fixed order, identified by an integer type. Now, sections are identified
by a named string (stored in a string pool after the section lists).

This will allow for razor files to contain arbitrary sections.

For bonus points, also drop the 4k section alignment and change the
magic byte string to "RZDB".

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