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),
33 /* the structure describing the options we take and the defaults */
34 static struct poptOption optionsTable[] = {
36 { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmBuildPoptTable, 0,
37 N_("Build options with [ <specfile> | <tarball> | <source package> ]:"),
40 { "quiet", '\0', 0, &quiet, 0, NULL, NULL},
42 { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmcliAllPoptTable, 0,
43 N_("Common options for all rpm modes and executables:"),
52 /* MiNT cannot dynamically increase the stack. */
53 long _stksize = 64 * 1024L;
57 static void argerror(const char * desc)
59 fprintf(stderr, _("%s: %s\n"), __progname, desc);
63 static void printVersion(FILE * fp)
65 fprintf(fp, _("RPM version %s\n"), rpmEVR);
68 static void printBanner(FILE * fp)
70 fprintf(fp, _("Copyright (C) 1998-2002 - Red Hat, Inc.\n"));
71 fprintf(fp, _("This program may be freely redistributed under the terms of the GNU GPL\n"));
74 static void printUsage(poptContext con, FILE * fp, int flags)
81 poptPrintHelp(con, fp, flags);
83 poptPrintUsage(con, fp, flags);
86 int main(int argc, char *argv[])
89 enum modes bigMode = MODE_BUILD;
90 BTA_t ba = &rpmBTArgs;
91 char * passPhrase = "";
95 const char *poptCtx = "rpmbuild";
102 #if HAVE_MCHECK_H && HAVE_MTRACE
103 mtrace(); /* Trace malloc only if MALLOC_TRACE=mtrace-output-file. */
105 setprogname(argv[0]); /* Retrofit glibc __progname */
107 /* XXX glibc churn sanity */
108 if (__progname == NULL) {
109 if ((__progname = strrchr(argv[0], '/')) != NULL) __progname++;
110 else __progname = argv[0];
113 #if defined(ENABLE_NLS)
114 /* set up the correct locale */
115 (void) setlocale(LC_ALL, "" );
117 bindtextdomain(PACKAGE, LOCALEDIR);
121 rpmSetVerbosity(RPMLOG_NOTICE); /* XXX silly use by showrc */
123 /* Make a first pass through the arguments, looking for --rcfile */
124 /* We need to handle that before dealing with the rest of the arguments. */
125 /* XXX popt argv definition should be fixed instead of casting... */
126 optCon = poptGetContext(poptCtx, argc, (const char **)argv, optionsTable, 0);
128 char *poptfile = rpmGenPath(rpmConfigDir(), LIBRPMALIAS_FILENAME, NULL);
129 (void) poptReadConfigFile(optCon, poptfile);
132 (void) poptReadDefaultConfig(optCon, 1);
133 poptSetExecPath(optCon, rpmConfigDir(), 1);
135 while ((arg = poptGetNextOpt(optCon)) > 0) {
136 optArg = poptGetOptArg(optCon);
140 fprintf(stderr, _("Internal error in argument processing (%d) :-(\n"), arg);
146 fprintf(stderr, "%s: %s\n",
147 poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
152 if (argc <= 1 || poptPeekArg(optCon) == NULL) {
153 printUsage(optCon, stderr, 0);
159 switch (ba->buildMode) {
160 case 'b': bigMode = MODE_BUILD; break;
161 case 't': bigMode = MODE_TARBUILD; break;
162 case 'B': bigMode = MODE_REBUILD; break;
163 case 'C': bigMode = MODE_RECOMPILE; break;
166 if (rpmcliRootDir && rpmcliRootDir[0] != '/') {
167 argerror(_("arguments to --root (-r) must begin with a /"));
171 rpmSetVerbosity(RPMLOG_WARNING);
174 if (bigMode == MODE_REBUILD || bigMode == MODE_BUILD ||
175 bigMode == MODE_TARBUILD)
177 if (poptPeekArg(optCon)) {
178 int sigTag = rpmLookupSignatureType(RPMLOOKUPSIG_QUERY);
186 passPhrase = rpmGetPassPhrase(_("Enter pass phrase: "), sigTag);
187 if (passPhrase == NULL) {
188 fprintf(stderr, _("Pass phrase check failed\n"));
192 fprintf(stderr, _("Pass phrase is good.\n"));
193 passPhrase = xstrdup(passPhrase);
197 _("Invalid %%_signature spec in macro file.\n"));
204 argerror(_("--sign may only be used during package building"));
207 /* Make rpmLookupSignatureType() return 0 ("none") from now on */
208 (void) rpmLookupSignatureType(RPMLOOKUPSIG_DISABLE);
211 if (rpmcliPipeOutput) {
213 fprintf(stderr, _("creating a pipe for --pipe failed: %m\n"));
217 if (!(pipeChild = fork())) {
218 (void) signal(SIGPIPE, SIG_DFL);
220 (void) dup2(p[0], STDIN_FILENO);
222 (void) execl("/bin/sh", "/bin/sh", "-c", rpmcliPipeOutput, NULL);
223 fprintf(stderr, _("exec failed\n"));
227 (void) dup2(p[1], STDOUT_FILENO);
232 (void) rpmtsSetRootDir(ts, rpmcliRootDir);
238 while (!rpmIsVerbose())
239 rpmIncreaseVerbosity();
242 RPMBUILD_PREP | RPMBUILD_BUILD | RPMBUILD_INSTALL | RPMBUILD_CHECK;
243 if (bigMode == MODE_REBUILD) {
244 ba->buildAmount |= RPMBUILD_PACKAGEBINARY;
245 ba->buildAmount |= RPMBUILD_RMSOURCE;
246 ba->buildAmount |= RPMBUILD_RMSPEC;
247 ba->buildAmount |= RPMBUILD_CLEAN;
248 ba->buildAmount |= RPMBUILD_RMBUILD;
251 while ((pkg = poptGetArg(optCon))) {
252 char * specFile = NULL;
255 ec = rpmInstallSource(ts, pkg, &specFile, &ba->cookie);
257 ba->rootdir = rpmcliRootDir;
258 ba->passPhrase = passPhrase;
259 ec = build(ts, specFile, ba, rpmcliRcfile);
261 ba->cookie = _free(ba->cookie);
262 specFile = _free(specFile);
273 if (!quiet) while (!rpmIsVerbose())
274 rpmIncreaseVerbosity();
276 switch (ba->buildChar) {
278 ba->buildAmount |= RPMBUILD_PACKAGESOURCE;
280 ba->buildAmount |= RPMBUILD_PACKAGEBINARY;
281 ba->buildAmount |= RPMBUILD_CLEAN;
282 if ((ba->buildChar == 'b') && ba->shortCircuit)
285 ba->buildAmount |= RPMBUILD_INSTALL;
286 ba->buildAmount |= RPMBUILD_CHECK;
287 if ((ba->buildChar == 'i') && ba->shortCircuit)
290 ba->buildAmount |= RPMBUILD_BUILD;
291 if ((ba->buildChar == 'c') && ba->shortCircuit)
294 ba->buildAmount |= RPMBUILD_PREP;
298 ba->buildAmount |= RPMBUILD_FILECHECK;
301 ba->buildAmount |= RPMBUILD_PACKAGESOURCE;
305 while ((pkg = poptGetArg(optCon))) {
306 ba->rootdir = rpmcliRootDir;
307 ba->passPhrase = passPhrase;
309 ec = build(ts, pkg, ba, rpmcliRcfile);
313 (void) rpmReadConfigFiles(rpmcliRcfile, NULL);
322 optCon = poptFreeContext(optCon);
324 rpmFreeMacros(rpmCLIMacroContext);
328 (void) fclose(stdout);
329 (void) waitpid(pipeChild, &status, 0);
332 /* keeps memory leak checkers quiet */
336 ba->buildRootOverride = _free(ba->buildRootOverride);
337 ba->targets = _free(ba->targets);
339 #if HAVE_MCHECK_H && HAVE_MTRACE
340 muntrace(); /* Trace malloc only if MALLOC_TRACE=mtrace-output-file. */
343 /* XXX Avoid exit status overflow. Status 255 is special to xargs(1) */
344 if (ec > 254) ec = 254;