]> git.pld-linux.org Git - packages/rpm-getdeps.git/blame - getdeps.c
- port to rpm 4.16
[packages/rpm-getdeps.git] / getdeps.c
CommitLineData
5f9d9873
JR
1// Copyright (C) 2003 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
2//
3// This program is free software; you can redistribute it and/or modify
4// it under the terms of the GNU General Public License as published by
5// the Free Software Foundation; version 2 of the License.
6//
7// This program is distributed in the hope that it will be useful,
8// but WITHOUT ANY WARRANTY; without even the implied warranty of
9// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10// GNU General Public License for more details.
11//
12// You should have received a copy of the GNU General Public License
13// along with this program; if not, write to the Free Software
14// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
15
16// version 0.0.7, 2003-11-21
17// * made it compilable with non-C99 compilers
18//
19// version 0.0.6, 2003-11-21
20// * added rpm-4.0.4 compatibility (define RPM404 macro)
21//
22// version 0.0.5, 2003-11-21
23// * added '--uid' and '--gid' options
24// * use macros for option-ids
25//
26// version 0.0.4, 2003-11-19
27// * set 'force' flag on parseSpec() to ignore missing sources & patches
28//
29// version 0.0.3, 2003-11-19
30// * fixed buffer-overflow in '--with[out]' statements
31//
32// version 0.0.2, 2003-11-19
33// * big rewrite; implemented nearly the full functionality
34//
35// version 0.0.1, 2003-11-19
36// * initial version
37
df2ac7c1 38#include <assert.h>
5f9d9873 39#include <getopt.h>
df2ac7c1
JR
40#include <grp.h>
41#include <libgen.h>
5f9d9873
JR
42#include <stdbool.h>
43#include <string.h>
5f9d9873
JR
44#include <sys/time.h>
45#include <sys/types.h>
df2ac7c1 46#include <unistd.h>
5f9d9873 47
df2ac7c1 48#include <header.h>
5f9d9873
JR
49#include <rpmbuild.h>
50#include <rpmlib.h>
df2ac7c1
JR
51#include <rpmlog.h>
52#include <rpmts.h>
5f9d9873
JR
53
54#define ARG_WITH 1024
55#define ARG_WITHOUT 1025
56#define ARG_DEFINE 1026
57#define ARG_TARGET 1027
58#define ARG_RCFILE 1028
59#define ARG_CHROOT 1029
60#define ARG_UID 1030
61#define ARG_GID 1031
62
63static struct option const
64CMDLINE_OPTIONS[] = {
65 { "help", no_argument, 0, 'h' },
66 { "version", no_argument, 0, 'v' },
67 { "with", required_argument, 0, ARG_WITH },
68 { "without", required_argument, 0, ARG_WITHOUT },
69 { "define", required_argument, 0, ARG_DEFINE },
70 { "target", required_argument, 0, ARG_TARGET },
71 { "rcfile", required_argument, 0, ARG_RCFILE },
72 { "chroot", required_argument, 0, ARG_CHROOT },
73 { "uid", required_argument, 0, ARG_UID },
74 { "gid", required_argument, 0, ARG_GID },
75 { 0,0,0,0 }
76};
77
78struct Arguments
79{
80 char const * target;
81 char const * rcfile;
82 char const * chroot;
83 uid_t uid;
84 gid_t gid;
85
86 struct {
87 char const ** values;
88 size_t cnt;
89 size_t reserved;
90 } macros;
91
92 char const * specfile;
93};
94
95struct DepSet {
df2ac7c1
JR
96 rpmtd flags;
97 rpmtd name;
98 rpmtd version;
99 ssize_t cnt;
5f9d9873
JR
100};
101
102inline static void
103writeStr(int fd, char const *cmd)
104{
105 (void)write(fd, cmd, strlen(cmd));
106}
107
108#define WRITE_MSG(FD,X) (void)(write(FD,X,sizeof(X)-1))
109#define WRITE_STR(FD,X) writeStr(FD,X)
110
111static void
112showHelp(int fd, char const *cmd, int res)
113{
114 char tmp[strlen(cmd)+1];
115 strcpy(tmp, cmd);
116
117 WRITE_MSG(fd, "Usage: ");
118 WRITE_STR(fd, basename(tmp));
119 WRITE_MSG(fd,
120 " [--define '<macro> <value>']* [--with[out] <key>]* [--chroot <dir>]\n"
121 " [--target <target>] [--rcfile <rcfile>] [--] <specfile>\n");
122 exit(res);
123}
124
125static void
126addDefine(struct Arguments *args, char const *val)
127{
128 register size_t c = args->macros.cnt;
129 if (args->macros.reserved <= c) {
130 args->macros.reserved *= 2;
131 args->macros.reserved += 1;
132
133 args->macros.values = realloc(args->macros.values,
134 args->macros.reserved * sizeof(char const *));
135 if (args->macros.values==0) {
136 perror("realloc()");
137 exit(1);
138 }
139 }
140
141 args->macros.values[c] = strdup(val);
142 ++args->macros.cnt;
143}
144
145static void
146setWithMacro(struct Arguments *args,
147 char const *name, char const *prefix, size_t prefix_len)
148{
149 size_t len = strlen(name);
150 char tmp[2*len + 2*prefix_len + sizeof("__ ---")];
151 char * ptr = tmp;
152
153 // set '_<prefix>_<name>'
154 *ptr++ = '_';
155 memcpy(ptr, prefix, prefix_len); ptr += prefix_len;
156 *ptr++ = '_';
157 memcpy(ptr, name, len); ptr += len;
158 *ptr++ = ' ';
159
160 // append ' --<prefix>-<name>'
161 *ptr++ = '-';
162 *ptr++ = '-';
163 memcpy(ptr, prefix, prefix_len); ptr += prefix_len;
164 *ptr++ = '-';
165 memcpy(ptr, name, len); ptr += len;
166 *ptr = '\0';
167
168 addDefine(args, tmp);
169}
170
171
172static void
173parseArgs(struct Arguments *args, int argc, char *argv[])
174{
175 while (1) {
176 int c = getopt_long(argc, argv, "", CMDLINE_OPTIONS, 0);
177 if (c==-1) break;
178 switch (c) {
179 case 'h' : showHelp(1, argv[0], 0);
180 case ARG_TARGET : args->target = optarg; break;
181 case ARG_RCFILE : args->rcfile = optarg; break;
182 case ARG_CHROOT : args->chroot = optarg; break;
183 case ARG_UID : args->uid = atoi(optarg); break;
184 case ARG_GID : args->gid = atoi(optarg); break;
185 case ARG_DEFINE : addDefine(args, optarg); break;
186 case ARG_WITH : setWithMacro(args, optarg, "with", 4); break;
187 case ARG_WITHOUT : setWithMacro(args, optarg, "without", 7); break;
188 default:
189 WRITE_MSG(2, "Try '");
190 WRITE_STR(2, argv[0]);
191 WRITE_MSG(2, " --help\" for more information.\n");
192 exit(1);
193 }
194 }
195
196 if (optind+1!=argc) {
197 write(2, "No/too much specfile(s) given; aborting\n", 40);
198 exit(1);
199 }
200
201 if (args->gid==(gid_t)(-1))
202 args->gid = args->uid;
203
204 args->specfile = argv[optind];
205}
206
207static void
208setMacros(char const * const *macros, size_t cnt)
209{
210 size_t i;
211 for (i=0; i<cnt; ++i)
212 rpmDefineMacro(rpmGlobalMacroContext, macros[i], 0);
213}
214
215static void
df2ac7c1 216printDepSet(struct DepSet set, char const *prefix)
5f9d9873
JR
217{
218 ssize_t i;
df2ac7c1
JR
219 for (i=0; i<set.cnt; ++i) {
220 printf("%s%08x %s %s\n", prefix, (uint32_t)rpmtdGetNumber(set.flags), rpmtdGetString(set.name), rpmtdGetString(set.version));
221 rpmtdNext(set.flags);
222 rpmtdNext(set.name);
223 rpmtdNext(set.version);
224 }
5f9d9873
JR
225}
226
227static void
228evaluateHeader(Header h)
229{
df2ac7c1
JR
230 struct DepSet buildreqs;
231 struct DepSet conflicts;
232
233 buildreqs.flags = rpmtdNew();
234 buildreqs.name = rpmtdNew();
235 buildreqs.version = rpmtdNew();
236 buildreqs.cnt = 0;
237
238 if (headerGet(h, RPMTAG_REQUIREFLAGS, buildreqs.flags, 0) &&
239 headerGet(h, RPMTAG_REQUIRENAME, buildreqs.name, 0) &&
240 headerGet(h, RPMTAG_REQUIREVERSION, buildreqs.version, 0)) {
241 assert(buildreqs.flags->count==buildreqs.name->count && buildreqs.name->count==buildreqs.version->count);
242 buildreqs.cnt = buildreqs.flags->count;
5f9d9873
JR
243 }
244
df2ac7c1
JR
245 conflicts.flags = rpmtdNew();
246 conflicts.name = rpmtdNew();
247 conflicts.version = rpmtdNew();
248 conflicts.cnt = 0;
249
250 if (headerGet(h, RPMTAG_CONFLICTFLAGS, conflicts.flags, 0) &&
251 headerGet(h, RPMTAG_CONFLICTNAME, conflicts.name, 0) &&
252 headerGet(h, RPMTAG_CONFLICTVERSION, conflicts.version, 0)) {
253 assert(conflicts.flags->count==conflicts.name->count && conflicts.name->count==conflicts.version->count);
254 conflicts.cnt = conflicts.flags->count;
5f9d9873
JR
255 }
256
df2ac7c1
JR
257 printDepSet(buildreqs, "+ ");
258 printDepSet(conflicts, "- ");
5f9d9873
JR
259}
260
261int main(int argc, char *argv[])
262{
263 struct Arguments args = { 0,0,0,-1,-1, {0,0,0}, 0 };
df2ac7c1 264 rpmSpec s;
5f9d9873
JR
265
266 parseArgs(&args, argc, argv);
267
268 if ((args.chroot && chroot(args.chroot)==-1) ||
269 (args.uid!=(uid_t)(-1) && (setgroups(0,0) ==-1 || getgroups(0,0)!=0)) ||
270 (args.gid!=(gid_t)(-1) && (setgid(args.gid)==-1 || getgid()!=args.gid)) ||
271 (args.uid!=(uid_t)(-1) && (setuid(args.uid)==-1 || getuid()!=args.uid))) {
272 perror("chroot/setuid/setgid()");
273 return EXIT_FAILURE;
274 }
5f9d9873 275
df2ac7c1 276 rpmSetVerbosity(RPMLOG_ERR);
5f9d9873 277
df2ac7c1
JR
278 rpmReadConfigFiles(args.rcfile, args.target);
279 setMacros(args.macros.values, args.macros.cnt);
5f9d9873 280
df2ac7c1
JR
281 s = rpmSpecParse(args.specfile, RPMSPEC_FORCE, NULL);
282 evaluateHeader(rpmSpecSourceHeader(s));
5f9d9873 283}
This page took 0.0937 seconds and 4 git commands to generate.