blob: 98a45d9cc701ebba68c6fd8cc86414de2d89c292 [file] [log] [blame]
Glenn L McGrathb72a7352002-12-10 00:17:22 +00001/* vi: set sw=4 ts=4: */
2/*
3 * Mini rpm applet for busybox
4 *
5 * Copyright (C) 2001,2002 by Laurence Anderson
6 *
Denys Vlasenko0ef64bd2010-08-16 20:14:46 +02007 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
Glenn L McGrathb72a7352002-12-10 00:17:22 +00008 */
9
Pere Orga1f4447b2011-03-27 22:40:30 +020010//usage:#define rpm_trivial_usage
11//usage: "-i PACKAGE.rpm; rpm -qp[ildc] PACKAGE.rpm"
12//usage:#define rpm_full_usage "\n\n"
13//usage: "Manipulate RPM packages\n"
14//usage: "\nCommands:"
15//usage: "\n -i Install package"
16//usage: "\n -qp Query package"
17//usage: "\nOptions:"
18//usage: "\n -i Show information"
19//usage: "\n -l List contents"
20//usage: "\n -d List documents"
21//usage: "\n -c List config files"
22
Denis Vlasenkob6adbf12007-05-26 19:00:18 +000023#include "libbb.h"
Denys Vlasenko833d4e72010-11-03 02:38:31 +010024#include "archive.h"
Denys Vlasenko27653ad2010-05-06 14:19:19 +000025#include "rpm.h"
Glenn L McGrath38386d72002-12-10 02:09:12 +000026
Denis Vlasenkof4c52b32006-12-22 15:03:50 +000027#define RPM_CHAR_TYPE 1
28#define RPM_INT8_TYPE 2
29#define RPM_INT16_TYPE 3
30#define RPM_INT32_TYPE 4
31/* #define RPM_INT64_TYPE 5 ---- These aren't supported (yet) */
32#define RPM_STRING_TYPE 6
33#define RPM_BIN_TYPE 7
34#define RPM_STRING_ARRAY_TYPE 8
35#define RPM_I18NSTRING_TYPE 9
Glenn L McGrathb72a7352002-12-10 00:17:22 +000036
Denis Vlasenkof4c52b32006-12-22 15:03:50 +000037#define TAG_NAME 1000
38#define TAG_VERSION 1001
39#define TAG_RELEASE 1002
40#define TAG_SUMMARY 1004
41#define TAG_DESCRIPTION 1005
42#define TAG_BUILDTIME 1006
43#define TAG_BUILDHOST 1007
44#define TAG_SIZE 1009
45#define TAG_VENDOR 1011
46#define TAG_LICENSE 1014
47#define TAG_PACKAGER 1015
48#define TAG_GROUP 1016
49#define TAG_URL 1020
50#define TAG_PREIN 1023
51#define TAG_POSTIN 1024
52#define TAG_FILEFLAGS 1037
53#define TAG_FILEUSERNAME 1039
54#define TAG_FILEGROUPNAME 1040
55#define TAG_SOURCERPM 1044
56#define TAG_PREINPROG 1085
57#define TAG_POSTINPROG 1086
58#define TAG_PREFIXS 1098
59#define TAG_DIRINDEXES 1116
60#define TAG_BASENAMES 1117
61#define TAG_DIRNAMES 1118
Denys Vlasenko27653ad2010-05-06 14:19:19 +000062
Denis Vlasenkof4c52b32006-12-22 15:03:50 +000063#define RPMFILE_CONFIG (1 << 0)
64#define RPMFILE_DOC (1 << 1)
Glenn L McGrathb72a7352002-12-10 00:17:22 +000065
66enum rpm_functions_e {
67 rpm_query = 1,
68 rpm_install = 2,
69 rpm_query_info = 4,
70 rpm_query_package = 8,
71 rpm_query_list = 16,
72 rpm_query_list_doc = 32,
73 rpm_query_list_config = 64
74};
75
76typedef struct {
Eric Andersendfcb5b02004-01-30 22:54:20 +000077 uint32_t tag; /* 4 byte tag */
78 uint32_t type; /* 4 byte type */
79 uint32_t offset; /* 4 byte offset */
80 uint32_t count; /* 4 byte count */
Glenn L McGrathb72a7352002-12-10 00:17:22 +000081} rpm_index;
82
83static void *map;
84static rpm_index **mytags;
85static int tagcount;
86
Denys Vlasenko5dfd9c42010-05-06 16:56:38 +020087static void extract_cpio(int fd, const char *source_rpm);
Bernhard Reutner-Fischerd591a362006-08-20 17:35:13 +000088static rpm_index **rpm_gettags(int fd, int *num_tags);
89static int bsearch_rpmtag(const void *key, const void *item);
Denis Vlasenkof4c52b32006-12-22 15:03:50 +000090static char *rpm_getstr(int tag, int itemindex);
Bernhard Reutner-Fischerd591a362006-08-20 17:35:13 +000091static int rpm_getint(int tag, int itemindex);
92static int rpm_getcount(int tag);
93static void fileaction_dobackup(char *filename, int fileref);
94static void fileaction_setowngrp(char *filename, int fileref);
95static void loop_through_files(int filetag, void (*fileaction)(char *filename, int fileref));
Glenn L McGrathb72a7352002-12-10 00:17:22 +000096
Denis Vlasenko9b49a5e2007-10-11 10:05:36 +000097int rpm_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
Glenn L McGrathb72a7352002-12-10 00:17:22 +000098int rpm_main(int argc, char **argv)
99{
100 int opt = 0, func = 0, rpm_fd, offset;
Denis Vlasenkof4c52b32006-12-22 15:03:50 +0000101 const int pagesize = getpagesize();
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000102
103 while ((opt = getopt(argc, argv, "iqpldc")) != -1) {
104 switch (opt) {
Denis Vlasenkof4c52b32006-12-22 15:03:50 +0000105 case 'i': /* First arg: Install mode, with q: Information */
106 if (!func) func = rpm_install;
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000107 else func |= rpm_query_info;
108 break;
Denis Vlasenkof4c52b32006-12-22 15:03:50 +0000109 case 'q': /* First arg: Query mode */
110 if (func) bb_show_usage();
111 func = rpm_query;
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000112 break;
Denis Vlasenkof4c52b32006-12-22 15:03:50 +0000113 case 'p': /* Query a package */
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000114 func |= rpm_query_package;
115 break;
Denis Vlasenkof4c52b32006-12-22 15:03:50 +0000116 case 'l': /* List files in a package */
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000117 func |= rpm_query_list;
118 break;
Denis Vlasenkof4c52b32006-12-22 15:03:50 +0000119 case 'd': /* List doc files in a package (implies list) */
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000120 func |= rpm_query_list;
121 func |= rpm_query_list_doc;
122 break;
Denis Vlasenkof4c52b32006-12-22 15:03:50 +0000123 case 'c': /* List config files in a package (implies list) */
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000124 func |= rpm_query_list;
125 func |= rpm_query_list_config;
126 break;
127 default:
Manuel Novoa III cad53642003-03-19 09:13:01 +0000128 bb_show_usage();
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000129 }
130 }
Denis Vlasenkof4c52b32006-12-22 15:03:50 +0000131 argv += optind;
Denis Vlasenko1a9e9bd2008-11-01 12:54:56 +0000132 //argc -= optind;
Denys Vlasenko2ec91ae2010-01-04 14:15:38 +0100133 if (!argv[0]) {
134 bb_show_usage();
135 }
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000136
Denis Vlasenkof4c52b32006-12-22 15:03:50 +0000137 while (*argv) {
Denys Vlasenko5dfd9c42010-05-06 16:56:38 +0200138 const char *source_rpm;
139
Denis Vlasenkof4c52b32006-12-22 15:03:50 +0000140 rpm_fd = xopen(*argv++, O_RDONLY);
141 mytags = rpm_gettags(rpm_fd, &tagcount);
142 if (!mytags)
143 bb_error_msg_and_die("error reading rpm header");
144 offset = xlseek(rpm_fd, 0, SEEK_CUR);
145 /* Mimimum is one page */
146 map = mmap(0, offset > pagesize ? (offset + offset % pagesize) : pagesize, PROT_READ, MAP_PRIVATE, rpm_fd, 0);
147
Denys Vlasenko5dfd9c42010-05-06 16:56:38 +0200148 source_rpm = rpm_getstr(TAG_SOURCERPM, 0);
149
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000150 if (func & rpm_install) {
Denis Vlasenkof4c52b32006-12-22 15:03:50 +0000151 /* Backup any config files */
152 loop_through_files(TAG_BASENAMES, fileaction_dobackup);
153 /* Extact the archive */
Denys Vlasenko5dfd9c42010-05-06 16:56:38 +0200154 extract_cpio(rpm_fd, source_rpm);
Denis Vlasenkof4c52b32006-12-22 15:03:50 +0000155 /* Set the correct file uid/gid's */
156 loop_through_files(TAG_BASENAMES, fileaction_setowngrp);
157 }
158 else if ((func & (rpm_query|rpm_query_package)) == (rpm_query|rpm_query_package)) {
159 if (!(func & (rpm_query_info|rpm_query_list))) {
160 /* If just a straight query, just give package name */
161 printf("%s-%s-%s\n", rpm_getstr(TAG_NAME, 0), rpm_getstr(TAG_VERSION, 0), rpm_getstr(TAG_RELEASE, 0));
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000162 }
163 if (func & rpm_query_info) {
164 /* Do the nice printout */
165 time_t bdate_time;
Denys Vlasenkodc698bb2010-01-09 19:10:49 +0100166 struct tm *bdate_ptm;
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000167 char bdatestring[50];
Denys Vlasenko27653ad2010-05-06 14:19:19 +0000168 const char *p;
169
170 p = rpm_getstr(TAG_PREFIXS, 0);
171 if (!p) p = "(not relocateable)";
172 printf("Name : %-29sRelocations: %s\n", rpm_getstr(TAG_NAME, 0), p);
173 p = rpm_getstr(TAG_VENDOR, 0);
174 if (!p) p = "(none)";
175 printf("Version : %-34sVendor: %s\n", rpm_getstr(TAG_VERSION, 0), p);
Denis Vlasenkof4c52b32006-12-22 15:03:50 +0000176 bdate_time = rpm_getint(TAG_BUILDTIME, 0);
Denys Vlasenkodc698bb2010-01-09 19:10:49 +0100177 bdate_ptm = localtime(&bdate_time);
178 strftime(bdatestring, 50, "%a %d %b %Y %T %Z", bdate_ptm);
Denis Vlasenkof4c52b32006-12-22 15:03:50 +0000179 printf("Release : %-30sBuild Date: %s\n", rpm_getstr(TAG_RELEASE, 0), bdatestring);
180 printf("Install date: %-30sBuild Host: %s\n", "(not installed)", rpm_getstr(TAG_BUILDHOST, 0));
Denys Vlasenko5dfd9c42010-05-06 16:56:38 +0200181 printf("Group : %-30sSource RPM: %s\n", rpm_getstr(TAG_GROUP, 0), source_rpm);
Denis Vlasenkof4c52b32006-12-22 15:03:50 +0000182 printf("Size : %-33dLicense: %s\n", rpm_getint(TAG_SIZE, 0), rpm_getstr(TAG_LICENSE, 0));
183 printf("URL : %s\n", rpm_getstr(TAG_URL, 0));
184 printf("Summary : %s\n", rpm_getstr(TAG_SUMMARY, 0));
185 printf("Description :\n%s\n", rpm_getstr(TAG_DESCRIPTION, 0));
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000186 }
187 if (func & rpm_query_list) {
188 int count, it, flags;
Denis Vlasenkof4c52b32006-12-22 15:03:50 +0000189 count = rpm_getcount(TAG_BASENAMES);
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000190 for (it = 0; it < count; it++) {
Denis Vlasenkof4c52b32006-12-22 15:03:50 +0000191 flags = rpm_getint(TAG_FILEFLAGS, it);
192 switch (func & (rpm_query_list_doc|rpm_query_list_config)) {
193 case rpm_query_list_doc:
194 if (!(flags & RPMFILE_DOC)) continue;
195 break;
196 case rpm_query_list_config:
197 if (!(flags & RPMFILE_CONFIG)) continue;
198 break;
199 case rpm_query_list_doc|rpm_query_list_config:
200 if (!(flags & (RPMFILE_CONFIG|RPMFILE_DOC))) continue;
201 break;
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000202 }
Denis Vlasenkof4c52b32006-12-22 15:03:50 +0000203 printf("%s%s\n",
204 rpm_getstr(TAG_DIRNAMES, rpm_getint(TAG_DIRINDEXES, it)),
205 rpm_getstr(TAG_BASENAMES, it));
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000206 }
207 }
208 }
Denis Vlasenkof4c52b32006-12-22 15:03:50 +0000209 free(mytags);
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000210 }
211 return 0;
212}
213
Denys Vlasenko5dfd9c42010-05-06 16:56:38 +0200214static void extract_cpio(int fd, const char *source_rpm)
Denis Vlasenkoac678ec2007-04-16 22:32:04 +0000215{
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000216 archive_handle_t *archive_handle;
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000217
Denys Vlasenko5dfd9c42010-05-06 16:56:38 +0200218 if (source_rpm != NULL) {
219 /* Binary rpm (it was built from some SRPM), install to root */
220 xchdir("/");
221 } /* else: SRPM, install to current dir */
222
Denis Vlasenkoc14d39e2007-06-08 13:05:39 +0000223 /* Initialize */
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000224 archive_handle = init_handle();
Denis Vlasenko13858992006-10-08 12:49:22 +0000225 archive_handle->seek = seek_by_read;
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000226 archive_handle->action_data = data_extract_all;
Denys Vlasenko27653ad2010-05-06 14:19:19 +0000227#if 0 /* For testing (rpm -i only lists the files in internal cpio): */
228 archive_handle->action_header = header_list;
229 archive_handle->action_data = data_skip;
230#endif
Denys Vlasenkod57d6262009-09-17 02:43:14 +0200231 archive_handle->ah_flags = ARCHIVE_RESTORE_DATE | ARCHIVE_CREATE_LEADING_DIRS
Denis Vlasenkoaa9eb1f2008-10-16 13:29:13 +0000232 /* compat: overwrite existing files.
233 * try "rpm -i foo.src.rpm" few times in a row -
234 * standard rpm will not complain.
235 * (TODO? real rpm creates "file;1234" and then renames it) */
Denys Vlasenkod57d6262009-09-17 02:43:14 +0200236 | ARCHIVE_UNLINK_OLD;
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000237 archive_handle->src_fd = fd;
Denis Vlasenkoa60936d2008-06-28 05:04:09 +0000238 /*archive_handle->offset = 0; - init_handle() did it */
Eric Andersenc7bda1c2004-03-15 08:29:22 +0000239
Denys Vlasenko27653ad2010-05-06 14:19:19 +0000240 setup_unzip_on_fd(archive_handle->src_fd /*, fail_if_not_detected: 1*/);
Denis Vlasenkof4c52b32006-12-22 15:03:50 +0000241 while (get_header_cpio(archive_handle) == EXIT_SUCCESS)
Denis Vlasenkoc14d39e2007-06-08 13:05:39 +0000242 continue;
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000243}
244
Bernhard Reutner-Fischerd591a362006-08-20 17:35:13 +0000245static rpm_index **rpm_gettags(int fd, int *num_tags)
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000246{
Denys Vlasenko27653ad2010-05-06 14:19:19 +0000247 /* We should never need more than 200 (shrink via realloc later) */
Denis Vlasenko1a9e9bd2008-11-01 12:54:56 +0000248 rpm_index **tags = xzalloc(200 * sizeof(tags[0]));
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000249 int pass, tagindex = 0;
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000250
Denis Vlasenkof4c52b32006-12-22 15:03:50 +0000251 xlseek(fd, 96, SEEK_CUR); /* Seek past the unused lead */
252
253 /* 1st pass is the signature headers, 2nd is the main stuff */
254 for (pass = 0; pass < 2; pass++) {
Denys Vlasenko27653ad2010-05-06 14:19:19 +0000255 struct rpm_header header;
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000256 rpm_index *tmpindex;
257 int storepos;
258
Denis Vlasenkof4c52b32006-12-22 15:03:50 +0000259 xread(fd, &header, sizeof(header));
Denys Vlasenko27653ad2010-05-06 14:19:19 +0000260 if (header.magic_and_ver != htonl(RPM_HEADER_MAGICnVER))
261 return NULL; /* Invalid magic, or not version 1 */
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000262 header.size = ntohl(header.size);
263 header.entries = ntohl(header.entries);
Denys Vlasenko27653ad2010-05-06 14:19:19 +0000264 storepos = xlseek(fd, 0, SEEK_CUR) + header.entries * 16;
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000265
266 while (header.entries--) {
Denis Vlasenko1a9e9bd2008-11-01 12:54:56 +0000267 tmpindex = tags[tagindex++] = xmalloc(sizeof(*tmpindex));
268 xread(fd, tmpindex, sizeof(*tmpindex));
Denis Vlasenkof4c52b32006-12-22 15:03:50 +0000269 tmpindex->tag = ntohl(tmpindex->tag);
270 tmpindex->type = ntohl(tmpindex->type);
271 tmpindex->count = ntohl(tmpindex->count);
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000272 tmpindex->offset = storepos + ntohl(tmpindex->offset);
Denis Vlasenkodeeed592008-07-08 05:14:36 +0000273 if (pass == 0)
Denis Vlasenkof4c52b32006-12-22 15:03:50 +0000274 tmpindex->tag -= 743;
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000275 }
Denys Vlasenko27653ad2010-05-06 14:19:19 +0000276 storepos = xlseek(fd, header.size, SEEK_CUR); /* Seek past store */
Denis Vlasenkof4c52b32006-12-22 15:03:50 +0000277 /* Skip padding to 8 byte boundary after reading signature headers */
Denis Vlasenkodeeed592008-07-08 05:14:36 +0000278 if (pass == 0)
Denys Vlasenko27653ad2010-05-06 14:19:19 +0000279 xlseek(fd, (-storepos) & 0x7, SEEK_CUR);
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000280 }
Denys Vlasenko27653ad2010-05-06 14:19:19 +0000281 /* realloc tags to save space */
282 tags = xrealloc(tags, tagindex * sizeof(tags[0]));
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000283 *num_tags = tagindex;
Denys Vlasenko27653ad2010-05-06 14:19:19 +0000284 /* All done, leave the file at the start of the gzipped cpio archive */
285 return tags;
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000286}
287
Bernhard Reutner-Fischerd591a362006-08-20 17:35:13 +0000288static int bsearch_rpmtag(const void *key, const void *item)
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000289{
Eric Andersen2cdd4d52006-01-30 18:33:12 +0000290 int *tag = (int *)key;
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000291 rpm_index **tmp = (rpm_index **) item;
Eric Andersen2cdd4d52006-01-30 18:33:12 +0000292 return (*tag - tmp[0]->tag);
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000293}
294
Bernhard Reutner-Fischerd591a362006-08-20 17:35:13 +0000295static int rpm_getcount(int tag)
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000296{
297 rpm_index **found;
Eric Andersen2cdd4d52006-01-30 18:33:12 +0000298 found = bsearch(&tag, mytags, tagcount, sizeof(struct rpmtag *), bsearch_rpmtag);
Denis Vlasenkof4c52b32006-12-22 15:03:50 +0000299 if (!found)
300 return 0;
301 return found[0]->count;
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000302}
303
Denis Vlasenkof4c52b32006-12-22 15:03:50 +0000304static char *rpm_getstr(int tag, int itemindex)
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000305{
306 rpm_index **found;
Eric Andersen2cdd4d52006-01-30 18:33:12 +0000307 found = bsearch(&tag, mytags, tagcount, sizeof(struct rpmtag *), bsearch_rpmtag);
Denis Vlasenkof4c52b32006-12-22 15:03:50 +0000308 if (!found || itemindex >= found[0]->count)
309 return NULL;
Denys Vlasenko27653ad2010-05-06 14:19:19 +0000310 if (found[0]->type == RPM_STRING_TYPE
311 || found[0]->type == RPM_I18NSTRING_TYPE
312 || found[0]->type == RPM_STRING_ARRAY_TYPE
313 ) {
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000314 int n;
Denys Vlasenko606291b2009-09-23 23:15:43 +0200315 char *tmpstr = (char *) map + found[0]->offset;
Denys Vlasenko27653ad2010-05-06 14:19:19 +0000316 for (n = 0; n < itemindex; n++)
Denis Vlasenkof4c52b32006-12-22 15:03:50 +0000317 tmpstr = tmpstr + strlen(tmpstr) + 1;
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000318 return tmpstr;
Denis Vlasenkof4c52b32006-12-22 15:03:50 +0000319 }
320 return NULL;
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000321}
322
Bernhard Reutner-Fischerd591a362006-08-20 17:35:13 +0000323static int rpm_getint(int tag, int itemindex)
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000324{
325 rpm_index **found;
Denis Vlasenkof4c52b32006-12-22 15:03:50 +0000326 int *tmpint; /* NB: using int8_t* would be easier to code */
327
Mike Frysinger19d70212005-04-23 01:43:07 +0000328 /* gcc throws warnings here when sizeof(void*)!=sizeof(int) ...
329 * it's ok to ignore it because tag won't be used as a pointer */
Eric Andersen2cdd4d52006-01-30 18:33:12 +0000330 found = bsearch(&tag, mytags, tagcount, sizeof(struct rpmtag *), bsearch_rpmtag);
Denis Vlasenkof4c52b32006-12-22 15:03:50 +0000331 if (!found || itemindex >= found[0]->count)
332 return -1;
333
Denys Vlasenko606291b2009-09-23 23:15:43 +0200334 tmpint = (int *) ((char *) map + found[0]->offset);
Denis Vlasenkof4c52b32006-12-22 15:03:50 +0000335
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000336 if (found[0]->type == RPM_INT32_TYPE) {
Denis Vlasenkof4c52b32006-12-22 15:03:50 +0000337 tmpint = (int *) ((char *) tmpint + itemindex*4);
338 /*return ntohl(*tmpint);*/
339 /* int can be != int32_t */
340 return ntohl(*(int32_t*)tmpint);
341 }
342 if (found[0]->type == RPM_INT16_TYPE) {
343 tmpint = (int *) ((char *) tmpint + itemindex*2);
344 /* ??? read int, and THEN ntohs() it?? */
345 /*return ntohs(*tmpint);*/
346 return ntohs(*(int16_t*)tmpint);
347 }
348 if (found[0]->type == RPM_INT8_TYPE) {
349 tmpint = (int *) ((char *) tmpint + itemindex);
350 /* ??? why we don't read byte here??? */
351 /*return ntohs(*tmpint);*/
352 return *(int8_t*)tmpint;
353 }
354 return -1;
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000355}
356
Bernhard Reutner-Fischerd591a362006-08-20 17:35:13 +0000357static void fileaction_dobackup(char *filename, int fileref)
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000358{
359 struct stat oldfile;
360 int stat_res;
361 char *newname;
Denis Vlasenkof4c52b32006-12-22 15:03:50 +0000362 if (rpm_getint(TAG_FILEFLAGS, fileref) & RPMFILE_CONFIG) {
363 /* Only need to backup config files */
364 stat_res = lstat(filename, &oldfile);
365 if (stat_res == 0 && S_ISREG(oldfile.st_mode)) {
366 /* File already exists - really should check MD5's etc to see if different */
Denis Vlasenko9cac5212006-09-09 12:24:19 +0000367 newname = xasprintf("%s.rpmorig", filename);
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000368 copy_file(filename, newname, FILEUTILS_RECUR | FILEUTILS_PRESERVE_STATUS);
369 remove_file(filename, FILEUTILS_RECUR | FILEUTILS_FORCE);
370 free(newname);
371 }
372 }
373}
374
Bernhard Reutner-Fischerd591a362006-08-20 17:35:13 +0000375static void fileaction_setowngrp(char *filename, int fileref)
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000376{
Denis Vlasenkoaa9eb1f2008-10-16 13:29:13 +0000377 /* real rpm warns: "user foo does not exist - using <you>" */
378 struct passwd *pw = getpwnam(rpm_getstr(TAG_FILEUSERNAME, fileref));
379 int uid = pw ? pw->pw_uid : getuid(); /* or euid? */
380 struct group *gr = getgrnam(rpm_getstr(TAG_FILEGROUPNAME, fileref));
381 int gid = gr ? gr->gr_gid : getgid();
Denis Vlasenkocf944462006-10-03 19:02:20 +0000382 chown(filename, uid, gid);
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000383}
384
Bernhard Reutner-Fischerd591a362006-08-20 17:35:13 +0000385static void loop_through_files(int filetag, void (*fileaction)(char *filename, int fileref))
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000386{
387 int count = 0;
Denis Vlasenkof4c52b32006-12-22 15:03:50 +0000388 while (rpm_getstr(filetag, count)) {
389 char* filename = xasprintf("%s%s",
390 rpm_getstr(TAG_DIRNAMES, rpm_getint(TAG_DIRINDEXES, count)),
391 rpm_getstr(TAG_BASENAMES, count));
Glenn L McGrathb72a7352002-12-10 00:17:22 +0000392 fileaction(filename, count++);
393 free(filename);
394 }
395}