2 const char *__progname;
11 #include <rpm/rpmcli.h>
12 #include <rpm/rpmlib.h> /* RPMSIGTAG, rpmReadPackageFile .. */
13 #include <rpm/rpmbuild.h>
14 #include <rpm/rpmlog.h>
15 #include <rpm/rpmfileutil.h>
16 #include <rpm/rpmdb.h>
17 #include <rpm/rpmps.h>
18 #include <rpm/rpmts.h>
19 #include "lib/signature.h"
25 MODE_BUILD = (1 << 4),
26 MODE_REBUILD = (1 << 5),
27 MODE_RECOMPILE = (1 << 8),
28 MODE_TARBUILD = (1 << 11),
29 #define MODES_BT (MODE_BUILD | MODE_TARBUILD | MODE_REBUILD | MODE_RECOMPILE)
34 #define MODES_FOR_DBPATH (MODES_BT)
35 #define MODES_FOR_NODEPS (MODES_BT)
36 #define MODES_FOR_TEST (MODES_BT)
37 #define MODES_FOR_ROOT (MODES_BT)
41 /* the structure describing the options we take and the defaults */
42 static struct poptOption optionsTable[] = {
44 { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmBuildPoptTable, 0,
45 N_("Build options with [ <specfile> | <tarball> | <source package> ]:"),
48 { "quiet", '\0', 0, &quiet, 0, NULL, NULL},
50 { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmcliAllPoptTable, 0,
51 N_("Common options for all rpm modes and executables:"),
60 /* MiNT cannot dynamically increase the stack. */
61 long _stksize = 64 * 1024L;
65 static void argerror(const char * desc)
67 fprintf(stderr, _("%s: %s\n"), __progname, desc);
71 static void printVersion(FILE * fp)
73 fprintf(fp, _("RPM version %s\n"), rpmEVR);
76 static void printBanner(FILE * fp)
78 fprintf(fp, _("Copyright (C) 1998-2002 - Red Hat, Inc.\n"));
79 fprintf(fp, _("This program may be freely redistributed under the terms of the GNU GPL\n"));
82 static void printUsage(poptContext con, FILE * fp, int flags)
89 poptPrintHelp(con, fp, flags);
91 poptPrintUsage(con, fp, flags);
94 int main(int argc, char *argv[])
97 enum modes bigMode = MODE_UNKNOWN;
98 BTA_t ba = &rpmBTArgs;
99 char * passPhrase = "";
102 const char *optArg, *poptCtx;
109 #if HAVE_MCHECK_H && HAVE_MTRACE
110 mtrace(); /* Trace malloc only if MALLOC_TRACE=mtrace-output-file. */
112 setprogname(argv[0]); /* Retrofit glibc __progname */
114 /* XXX glibc churn sanity */
115 if (__progname == NULL) {
116 if ((__progname = strrchr(argv[0], '/')) != NULL) __progname++;
117 else __progname = argv[0];
120 /* Set the major mode based on argv[0] */
121 if (rstreq(__progname, "rpmbuild")) bigMode = MODE_BUILD;
123 #if defined(ENABLE_NLS)
124 /* set up the correct locale */
125 (void) setlocale(LC_ALL, "" );
127 bindtextdomain(PACKAGE, LOCALEDIR);
131 rpmSetVerbosity(RPMLOG_NOTICE); /* XXX silly use by showrc */
133 /* Only build has it's own set of aliases, everything else uses rpm */
134 poptCtx = "rpmbuild";
136 /* Make a first pass through the arguments, looking for --rcfile */
137 /* We need to handle that before dealing with the rest of the arguments. */
138 /* XXX popt argv definition should be fixed instead of casting... */
139 optCon = poptGetContext(poptCtx, argc, (const char **)argv, optionsTable, 0);
141 char *poptfile = rpmGenPath(rpmConfigDir(), LIBRPMALIAS_FILENAME, NULL);
142 (void) poptReadConfigFile(optCon, poptfile);
145 (void) poptReadDefaultConfig(optCon, 1);
146 poptSetExecPath(optCon, rpmConfigDir(), 1);
148 while ((arg = poptGetNextOpt(optCon)) > 0) {
149 optArg = poptGetOptArg(optCon);
153 fprintf(stderr, _("Internal error in argument processing (%d) :-(\n"), arg);
159 fprintf(stderr, "%s: %s\n",
160 poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
167 switch (ba->buildMode) {
168 case 'b': bigMode = MODE_BUILD; break;
169 case 't': bigMode = MODE_TARBUILD; break;
170 case 'B': bigMode = MODE_REBUILD; break;
171 case 'C': bigMode = MODE_RECOMPILE; break;
174 if ((ba->buildAmount & RPMBUILD_RMSOURCE) && bigMode == MODE_UNKNOWN)
175 bigMode = MODE_BUILD;
177 if ((ba->buildAmount & RPMBUILD_RMSPEC) && bigMode == MODE_UNKNOWN)
178 bigMode = MODE_BUILD;
180 if (ba->buildRootOverride && bigMode != MODE_BUILD &&
181 bigMode != MODE_REBUILD && bigMode != MODE_TARBUILD) {
182 argerror("--buildroot may only be used during package builds");
185 if (rpmcliRootDir && rpmcliRootDir[1] && (bigMode & ~MODES_FOR_ROOT))
186 argerror(_("--root (-r) may only be specified during "
187 "installation, erasure, querying, and "
188 "database rebuilds"));
191 switch (urlIsURL(rpmcliRootDir)) {
193 if (bigMode & MODES_FOR_ROOT)
196 if (rpmcliRootDir[0] != '/')
197 argerror(_("arguments to --root (-r) must begin with a /"));
203 rpmSetVerbosity(RPMLOG_WARNING);
206 if (bigMode == MODE_REBUILD || bigMode == MODE_BUILD ||
207 bigMode == MODE_TARBUILD)
213 if ((av = poptGetArgs(optCon)) == NULL) {
214 fprintf(stderr, _("no files to sign\n"));
218 if (stat(*av, &sb)) {
219 fprintf(stderr, _("cannot access file %s\n"), *av);
230 if (poptPeekArg(optCon)) {
231 int sigTag = rpmLookupSignatureType(RPMLOOKUPSIG_QUERY);
239 passPhrase = rpmGetPassPhrase(_("Enter pass phrase: "), sigTag);
240 if (passPhrase == NULL) {
241 fprintf(stderr, _("Pass phrase check failed\n"));
245 fprintf(stderr, _("Pass phrase is good.\n"));
246 passPhrase = xstrdup(passPhrase);
250 _("Invalid %%_signature spec in macro file.\n"));
257 argerror(_("--sign may only be used during package building"));
260 /* Make rpmLookupSignatureType() return 0 ("none") from now on */
261 (void) rpmLookupSignatureType(RPMLOOKUPSIG_DISABLE);
264 if (rpmcliPipeOutput) {
266 fprintf(stderr, _("creating a pipe for --pipe failed: %m\n"));
270 if (!(pipeChild = fork())) {
271 (void) signal(SIGPIPE, SIG_DFL);
273 (void) dup2(p[0], STDIN_FILENO);
275 (void) execl("/bin/sh", "/bin/sh", "-c", rpmcliPipeOutput, NULL);
276 fprintf(stderr, _("exec failed\n"));
280 (void) dup2(p[1], STDOUT_FILENO);
285 (void) rpmtsSetRootDir(ts, rpmcliRootDir);
291 while (!rpmIsVerbose())
292 rpmIncreaseVerbosity();
294 if (!poptPeekArg(optCon))
295 argerror(_("no packages files given for rebuild"));
298 RPMBUILD_PREP | RPMBUILD_BUILD | RPMBUILD_INSTALL | RPMBUILD_CHECK;
299 if (bigMode == MODE_REBUILD) {
300 ba->buildAmount |= RPMBUILD_PACKAGEBINARY;
301 ba->buildAmount |= RPMBUILD_RMSOURCE;
302 ba->buildAmount |= RPMBUILD_RMSPEC;
303 ba->buildAmount |= RPMBUILD_CLEAN;
304 ba->buildAmount |= RPMBUILD_RMBUILD;
307 while ((pkg = poptGetArg(optCon))) {
308 char * specFile = NULL;
311 ec = rpmInstallSource(ts, pkg, &specFile, &ba->cookie);
313 ba->rootdir = rpmcliRootDir;
314 ba->passPhrase = passPhrase;
315 ec = build(ts, specFile, ba, rpmcliRcfile);
317 ba->cookie = _free(ba->cookie);
318 specFile = _free(specFile);
329 if (!quiet) while (!rpmIsVerbose())
330 rpmIncreaseVerbosity();
332 switch (ba->buildChar) {
334 ba->buildAmount |= RPMBUILD_PACKAGESOURCE;
336 ba->buildAmount |= RPMBUILD_PACKAGEBINARY;
337 ba->buildAmount |= RPMBUILD_CLEAN;
338 if ((ba->buildChar == 'b') && ba->shortCircuit)
341 ba->buildAmount |= RPMBUILD_INSTALL;
342 ba->buildAmount |= RPMBUILD_CHECK;
343 if ((ba->buildChar == 'i') && ba->shortCircuit)
346 ba->buildAmount |= RPMBUILD_BUILD;
347 if ((ba->buildChar == 'c') && ba->shortCircuit)
350 ba->buildAmount |= RPMBUILD_PREP;
354 ba->buildAmount |= RPMBUILD_FILECHECK;
357 ba->buildAmount |= RPMBUILD_PACKAGESOURCE;
361 if (!poptPeekArg(optCon)) {
362 if (bigMode == MODE_BUILD)
363 argerror(_("no spec files given for build"));
365 argerror(_("no tar files given for build"));
368 while ((pkg = poptGetArg(optCon))) {
369 ba->rootdir = rpmcliRootDir;
370 ba->passPhrase = passPhrase;
372 ec = build(ts, pkg, ba, rpmcliRcfile);
376 (void) rpmReadConfigFiles(rpmcliRcfile, NULL);
381 if (poptPeekArg(optCon) != NULL || argc <= 1 || rpmIsVerbose()) {
382 printUsage(optCon, stderr, 0);
392 optCon = poptFreeContext(optCon);
394 rpmFreeMacros(rpmCLIMacroContext);
398 (void) fclose(stdout);
399 (void) waitpid(pipeChild, &status, 0);
402 /* keeps memory leak checkers quiet */
406 ba->buildRootOverride = _free(ba->buildRootOverride);
407 ba->targets = _free(ba->targets);
409 #if HAVE_MCHECK_H && HAVE_MTRACE
410 muntrace(); /* Trace malloc only if MALLOC_TRACE=mtrace-output-file. */
413 /* XXX Avoid exit status overflow. Status 255 is special to xargs(1) */
414 if (ec > 254) ec = 254;