- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List
- Globals

# rpmbuild.c

Go to the documentation of this file.

    00001 #include "system.h"
    00002 const char *__progname;
    00003
    00004 #include <errno.h>
    00005 #include <libgen.h>
    00006 #include <ctype.h>
    00007
    00008 #include <rpm/rpmcli.h>
    00009 #include <rpm/rpmlib.h>                 /* RPMSIGTAG, rpmReadPackageFile .. */
    00010 #include <rpm/rpmbuild.h>
    00011 #include <rpm/rpmlog.h>
    00012 #include <rpm/rpmfileutil.h>
    00013 #include <rpm/rpmdb.h>
    00014 #include <rpm/rpmps.h>
    00015 #include <rpm/rpmts.h>
    00016 #include "lib/signature.h"
    00017 #include "cliutils.h"
    00018
    00019 #include "debug.h"
    00020
    00021 static struct rpmBuildArguments_s rpmBTArgs;
    00022
    00023 #define POPT_NOLANG             -1012
    00024 #define POPT_RMSOURCE           -1013
    00025 #define POPT_RMBUILD            -1014
    00026 #define POPT_BUILDROOT          -1015
    00027 #define POPT_TARGETPLATFORM     -1016
    00028 #define POPT_NOBUILD            -1017
    00029 #define POPT_RMSPEC             -1019
    00030 #define POPT_NODIRTOKENS        -1020
    00031
    00032 #define POPT_REBUILD            0x4220
    00033 #define POPT_RECOMPILE          0x4320
    00034 #define POPT_BA                 0x6261
    00035 #define POPT_BB                 0x6262
    00036 #define POPT_BC                 0x6263
    00037 #define POPT_BI                 0x6269
    00038 #define POPT_BL                 0x626c
    00039 #define POPT_BP                 0x6270
    00040 #define POPT_BS                 0x6273
    00041 #define POPT_TA                 0x7461
    00042 #define POPT_TB                 0x7462
    00043 #define POPT_TC                 0x7463
    00044 #define POPT_TI                 0x7469
    00045 #define POPT_TL                 0x746c
    00046 #define POPT_TP                 0x7470
    00047 #define POPT_TS                 0x7473
    00048
    00049 extern int _fsm_debug;
    00050
    00051 static rpmSpecFlags spec_flags = 0;
    00052 static int noDeps = 0;
    00053 static int shortCircuit = 0;
    00054 static char buildMode = 0;
    00055 static char buildChar = 0;
    00056 static ARGV_t build_targets = NULL;
    00058 static void buildArgCallback( poptContext con,
    00059         enum poptCallbackReason reason,
    00060         const struct poptOption * opt, const char * arg,
    00061         const void * data)
    00062 {
    00063     BTA_t rba = &rpmBTArgs;
    00064
    00065     switch (opt->val) {
    00066     case POPT_REBUILD:
    00067     case POPT_RECOMPILE:
    00068     case POPT_BA:
    00069     case POPT_BB:
    00070     case POPT_BC:
    00071     case POPT_BI:
    00072     case POPT_BL:
    00073     case POPT_BP:
    00074     case POPT_BS:
    00075     case POPT_TA:
    00076     case POPT_TB:
    00077     case POPT_TC:
    00078     case POPT_TI:
    00079     case POPT_TL:
    00080     case POPT_TP:
    00081     case POPT_TS:
    00082         if (opt->val == POPT_BS || opt->val == POPT_TS)
    00083             noDeps = 1;
    00084         if (buildMode == '\0' && buildChar == '\0') {
    00085             buildMode = (((unsigned)opt->val) >> 8) & 0xff;
    00086             buildChar = (opt->val     ) & 0xff;
    00087         }
    00088         break;
    00089
    00090     case POPT_NODIRTOKENS: rba->pkgFlags |= RPMBUILD_PKG_NODIRTOKENS; break;
    00091     case POPT_NOBUILD: rba->buildAmount |= RPMBUILD_NOBUILD; break;
    00092     case POPT_NOLANG: spec_flags |= RPMSPEC_NOLANG; break;
    00093     case POPT_RMSOURCE: rba->buildAmount |= RPMBUILD_RMSOURCE; break;
    00094     case POPT_RMSPEC: rba->buildAmount |= RPMBUILD_RMSPEC; break;
    00095     case POPT_RMBUILD: rba->buildAmount |= RPMBUILD_RMBUILD; break;
    00096     case POPT_BUILDROOT:
    00097         if (rba->buildRootOverride) {
    00098             rpmlog(RPMLOG_ERR, _("buildroot already specified, ignoring %s\n"), arg);
    00099             break;
    00100         }
    00101         rba->buildRootOverride = xstrdup(arg);
    00102         break;
    00103     case POPT_TARGETPLATFORM:
    00104         argvSplit(&build_targets, arg, ",");
    00105         break;
    00106
    00107     case RPMCLI_POPT_FORCE:
    00108         spec_flags |= RPMSPEC_FORCE;
    00109         break;
    00110
    00111     }
    00112 }
    00113
    00114 static struct poptOption rpmBuildPoptTable[] = {
    00115  { NULL, '\0', POPT_ARG_CALLBACK | POPT_CBFLAG_INC_DATA | POPT_CBFLAG_CONTINUE,
    00116         buildArgCallback, 0, NULL, NULL },
    00117
    00118  { "bp", 0, POPT_ARGFLAG_ONEDASH, 0, POPT_BP,
    00119         N_("build through %prep (unpack sources and apply patches) from <specfile>"),
    00120         N_("<specfile>") },
    00121  { "bc", 0, POPT_ARGFLAG_ONEDASH, 0, POPT_BC,
    00122         N_("build through %build (%prep, then compile) from <specfile>"),
    00123         N_("<specfile>") },
    00124  { "bi", 0, POPT_ARGFLAG_ONEDASH, 0, POPT_BI,
    00125         N_("build through %install (%prep, %build, then install) from <specfile>"),
    00126         N_("<specfile>") },
    00127  { "bl", 0, POPT_ARGFLAG_ONEDASH, 0, POPT_BL,
    00128         N_("verify %files section from <specfile>"),
    00129         N_("<specfile>") },
    00130  { "ba", 0, POPT_ARGFLAG_ONEDASH, 0, POPT_BA,
    00131         N_("build source and binary packages from <specfile>"),
    00132         N_("<specfile>") },
    00133  { "bb", 0, POPT_ARGFLAG_ONEDASH, 0, POPT_BB,
    00134         N_("build binary package only from <specfile>"),
    00135         N_("<specfile>") },
    00136  { "bs", 0, POPT_ARGFLAG_ONEDASH, 0, POPT_BS,
    00137         N_("build source package only from <specfile>"),
    00138         N_("<specfile>") },
    00139
    00140  { "tp", 0, POPT_ARGFLAG_ONEDASH, 0, POPT_TP,
    00141         N_("build through %prep (unpack sources and apply patches) from <tarball>"),
    00142         N_("<tarball>") },
    00143  { "tc", 0, POPT_ARGFLAG_ONEDASH, 0, POPT_TC,
    00144         N_("build through %build (%prep, then compile) from <tarball>"),
    00145         N_("<tarball>") },
    00146  { "ti", 0, POPT_ARGFLAG_ONEDASH, 0, POPT_TI,
    00147         N_("build through %install (%prep, %build, then install) from <tarball>"),
    00148         N_("<tarball>") },
    00149  { "tl", 0, POPT_ARGFLAG_ONEDASH|POPT_ARGFLAG_DOC_HIDDEN, 0, POPT_TL,
    00150         N_("verify %files section from <tarball>"),
    00151         N_("<tarball>") },
    00152  { "ta", 0, POPT_ARGFLAG_ONEDASH, 0, POPT_TA,
    00153         N_("build source and binary packages from <tarball>"),
    00154         N_("<tarball>") },
    00155  { "tb", 0, POPT_ARGFLAG_ONEDASH, 0, POPT_TB,
    00156         N_("build binary package only from <tarball>"),
    00157         N_("<tarball>") },
    00158  { "ts", 0, POPT_ARGFLAG_ONEDASH, 0, POPT_TS,
    00159         N_("build source package only from <tarball>"),
    00160         N_("<tarball>") },
    00161
    00162  { "rebuild", '\0', 0, 0, POPT_REBUILD,
    00163         N_("build binary package from <source package>"),
    00164         N_("<source package>") },
    00165  { "recompile", '\0', 0, 0, POPT_RECOMPILE,
    00166         N_("build through %install (%prep, %build, then install) from <source package>"),
    00167         N_("<source package>") },
    00168
    00169  { "buildroot", '\0', POPT_ARG_STRING, 0,  POPT_BUILDROOT,
    00170         N_("override build root"), "DIRECTORY" },
    00171  { "clean", '\0', 0, 0, POPT_RMBUILD,
    00172         N_("remove build tree when done"), NULL},
    00173  { "force", '\0', POPT_ARGFLAG_DOC_HIDDEN, 0, RPMCLI_POPT_FORCE,
    00174         N_("ignore ExcludeArch: directives from spec file"), NULL},
    00175  { "fsmdebug", '\0', (POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN), &_fsm_debug, -1,
    00176         N_("debug file state machine"), NULL},
    00177  { "nobuild", '\0', 0, 0,  POPT_NOBUILD,
    00178         N_("do not execute any stages of the build"), NULL },
    00179  { "nodeps", '\0', POPT_ARG_VAL, &noDeps, 1,
    00180         N_("do not verify build dependencies"), NULL },
    00181  { "nodirtokens", '\0', 0, 0, POPT_NODIRTOKENS,
    00182         N_("generate package header(s) compatible with (legacy) rpm v3 packaging"),
    00183         NULL},
    00184
    00185  { "nolang", '\0', POPT_ARGFLAG_DOC_HIDDEN, 0, POPT_NOLANG,
    00186         N_("do not accept i18N msgstr's from specfile"), NULL},
    00187  { "rmsource", '\0', 0, 0, POPT_RMSOURCE,
    00188         N_("remove sources when done"), NULL},
    00189  { "rmspec", '\0', 0, 0, POPT_RMSPEC,
    00190         N_("remove specfile when done"), NULL},
    00191  { "short-circuit", '\0', POPT_ARG_VAL, &shortCircuit,  1,
    00192         N_("skip straight to specified stage (only for c,i)"), NULL },
    00193  { "target", '\0', POPT_ARG_STRING, 0,  POPT_TARGETPLATFORM,
    00194         N_("override target platform"), "CPU-VENDOR-OS" },
    00195    POPT_TABLEEND
    00196 };
    00197
    00198 enum modes {
    00199     MODE_BUILD          = (1 <<  4),
    00200     MODE_REBUILD        = (1 <<  5),
    00201     MODE_RECOMPILE      = (1 <<  8),
    00202     MODE_TARBUILD       = (1 << 11),
    00203 };
    00204
    00205 static int quiet;
    00206
    00207 /* the structure describing the options we take and the defaults */
    00208 static struct poptOption optionsTable[] = {
    00209
    00210  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmBuildPoptTable, 0,
    00211         N_("Build options with [ <specfile> | <tarball> | <source package> ]:"),
    00212         NULL },
    00213
    00214  { "quiet", '\0', POPT_ARGFLAG_DOC_HIDDEN, &quiet, 0, NULL, NULL},
    00215
    00216  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, rpmcliAllPoptTable, 0,
    00217         N_("Common options for all rpm modes and executables:"),
    00218         NULL },
    00219
    00220    POPT_AUTOALIAS
    00221    POPT_AUTOHELP
    00222    POPT_TABLEEND
    00223 };
    00224
    00225 static int checkSpec(rpmts ts, rpmSpec spec)
    00226 {
    00227     int rc;
    00228     rpmps ps = rpmSpecCheckDeps(ts, spec);
    00229
    00230     if (ps) {
    00231         rpmlog(RPMLOG_ERR, _("Failed build dependencies:\n"));
    00232         rpmpsPrint(NULL, ps);
    00233     }
    00234     rc = (ps != NULL);
    00235     ps = rpmpsFree(ps);
    00236     return rc;
    00237 }
    00238
    00239 static int isSpecFile(const char * specfile)
    00240 {
    00241     char buf[256];
    00242     const char * s;
    00243     FILE * f;
    00244     int count;
    00245     int checking;
    00246
    00247     f = fopen(specfile, "r");
    00248     if (f == NULL || ferror(f)) {
    00249         rpmlog(RPMLOG_ERR, _("Unable to open spec file %s: %s\n"),
    00250                 specfile, strerror(errno));
    00251         return 0;
    00252     }
    00253     count = fread(buf, sizeof(buf[0]), sizeof(buf), f);
    00254     (void) fclose(f);
    00255
    00256     if (count == 0)
    00257         return 0;
    00258
    00259     checking = 1;
    00260     for (s = buf; count--; s++) {
    00261         switch (*s) {
    00262         case '\r':
    00263         case '\n':
    00264             checking = 1;
    00265             break;
    00266         case ':':
    00267             checking = 0;
    00268             break;
    00269         default:
    00270 #if 0
    00271             if (checking && !(isprint(*s) || isspace(*s))) return 0;
    00272             break;
    00273 #else
    00274             if (checking && !(isprint(*s) || isspace(*s)) && *(unsigned char *)s < 32) return 0;
    00275             break;
    00276 #endif
    00277         }
    00278     }
    00279     return 1;
    00280 }
    00281
    00282 /*
    00283  * Try to find a spec from a tarball pointed to by arg.
    00284  * Return absolute path to spec name on success, otherwise NULL.
    00285  */
    00286 static char * getTarSpec(const char *arg)
    00287 {
    00288     char *specFile = NULL;
    00289     char *specDir;
    00290     char *specBase;
    00291     char *tmpSpecFile;
    00292     const char **spec;
    00293     char tarbuf[BUFSIZ];
    00294     int gotspec = 0, res;
    00295     static const char *tryspec[] = { "Specfile", "\\*.spec", NULL };
    00296
    00297     specDir = rpmGetPath("%{_specdir}", NULL);
    00298     tmpSpecFile = rpmGetPath("%{_specdir}/", "rpm-spec.XXXXXX", NULL);
    00299
    00300     (void) close(mkstemp(tmpSpecFile));
    00301
    00302     for (spec = tryspec; *spec != NULL; spec++) {
    00303         FILE *fp;
    00304         char *cmd;
    00305
    00306         cmd = rpmExpand("%{uncompress: ", arg, "} | ",
    00307                         "%{__tar} xOvf - --wildcards ", *spec,
    00308                         " 2>&1 > ", tmpSpecFile, NULL);
    00309
    00310         if (!(fp = popen(cmd, "r"))) {
    00311             rpmlog(RPMLOG_ERR, _("Failed to open tar pipe: %m\n"));
    00312         } else {
    00313             char *fok;
    00314             for (;;) {
    00315                 fok = fgets(tarbuf, sizeof(tarbuf) - 1, fp);
    00316                 /* tar sometimes prints "tar: Record size = 16" messages */
    00317                 if (!fok || strncmp(fok, "tar: ", 5) != 0)
    00318                     break;
    00319             }
    00320             pclose(fp);
    00321             gotspec = (fok != NULL) && isSpecFile(tmpSpecFile);
    00322         }
    00323
    00324         if (!gotspec)
    00325             unlink(tmpSpecFile);
    00326         free(cmd);
    00327     }
    00328
    00329     if (!gotspec) {
    00330         rpmlog(RPMLOG_ERR, _("Failed to read spec file from %s\n"), arg);
    00331         goto exit;
    00332     }
    00333
    00334     specBase = basename(tarbuf);
    00335     /* remove trailing \n */
    00336     specBase[strlen(specBase)-1] = '\0';
    00337
    00338     rasprintf(&specFile, "%s/%s", specDir, specBase);
    00339     res = rename(tmpSpecFile, specFile);
    00340
    00341     if (res) {
    00342         rpmlog(RPMLOG_ERR, _("Failed to rename %s to %s: %m\n"),
    00343                 tmpSpecFile, specFile);
    00344         free(specFile);
    00345         specFile = NULL;
    00346     } else {
    00347         /* mkstemp() can give unnecessarily strict permissions, fixup */
    00348         mode_t mask;
    00349         umask(mask = umask(0));
    00350         (void) chmod(specFile, 0666 & ~mask);
    00351     }
    00352
    00353 exit:
    00354     (void) unlink(tmpSpecFile);
    00355     free(tmpSpecFile);
    00356     free(specDir);
    00357     return specFile;
    00358 }
    00359
    00360 static int buildForTarget(rpmts ts, const char * arg, BTA_t ba)
    00361 {
    00362     int buildAmount = ba->buildAmount;
    00363     char * buildRootURL = NULL;
    00364     char * specFile = NULL;
    00365     rpmSpec spec = NULL;
    00366     int rc = 1; /* assume failure */
    00367     int justRm = ((buildAmount & ~(RPMBUILD_RMSOURCE|RPMBUILD_RMSPEC)) == 0);
    00368     rpmSpecFlags specFlags = spec_flags;
    00369
    00370 #ifndef DYING
    00371     rpmSetTables(RPM_MACHTABLE_BUILDARCH, RPM_MACHTABLE_BUILDOS);
    00372 #endif
    00373
    00374     if (ba->buildRootOverride)
    00375         buildRootURL = rpmGenPath(NULL, ba->buildRootOverride, NULL);
    00376
    00377     /* Create build tree if necessary */
    00378     const char * buildtree = "%{_topdir}:%{_specdir}:%{_sourcedir}:%{_builddir}:%{_rpmdir}:%{_srcrpmdir}:%{_buildrootdir}";
    00379     const char * rootdir = rpmtsRootDir(ts);
    00380     if (rpmMkdirs(!rstreq(rootdir, "/") ? rootdir : NULL , buildtree)) {
    00381         goto exit;
    00382     }
    00383
    00384     if (buildMode == 't') {
    00385         char *srcdir = NULL, *dir;
    00386
    00387         specFile = getTarSpec(arg);
    00388         if (!specFile)
    00389             goto exit;
    00390
    00391         /* Make the directory of the tarball %_sourcedir for this run */
    00392         /* dirname() may modify contents so extra hoops needed. */
    00393         if (*arg != '/') {
    00394             dir = rpmGetCwd();
    00395             rstrscat(&dir, "/", arg, NULL);
    00396         } else {
    00397             dir = xstrdup(arg);
    00398         }
    00399         srcdir = dirname(dir);
    00400         addMacro(NULL, "_sourcedir", NULL, srcdir, RMIL_TARBALL);
    00401         free(dir);
    00402     } else {
    00403         specFile = xstrdup(arg);
    00404     }
    00405
    00406     if (*specFile != '/') {
    00407         char *cwd = rpmGetCwd();
    00408         char *s = NULL;
    00409         rasprintf(&s, "%s/%s", cwd, specFile);
    00410         free(cwd);
    00411         free(specFile);
    00412         specFile = s;
    00413     }
    00414
    00415     struct stat st;
    00416     if (stat(specFile, &st) < 0) {
    00417         rpmlog(RPMLOG_ERR, _("failed to stat %s: %m\n"), specFile);
    00418         goto exit;
    00419     }
    00420     if (! S_ISREG(st.st_mode)) {
    00421         rpmlog(RPMLOG_ERR, _("File %s is not a regular file.\n"), specFile);
    00422         goto exit;
    00423     }
    00424
    00425     /* Try to verify that the file is actually a specfile */
    00426     if (!isSpecFile(specFile)) {
    00427         rpmlog(RPMLOG_ERR,
    00428                 _("File %s does not appear to be a specfile.\n"), specFile);
    00429         goto exit;
    00430     }
    00431
    00432     /* Don't parse spec if only its removal is requested */
    00433     if (ba->buildAmount == RPMBUILD_RMSPEC) {
    00434         rc = unlink(specFile);
    00435         goto exit;
    00436     }
    00437
    00438     /* Parse the spec file */
    00439 #define _anyarch(_f)    \
    00440 (((_f)&(RPMBUILD_PREP|RPMBUILD_BUILD|RPMBUILD_INSTALL|RPMBUILD_PACKAGEBINARY)) == 0)
    00441     if (_anyarch(buildAmount))
    00442         specFlags |= RPMSPEC_ANYARCH;
    00443 #undef  _anyarch
    00444
    00445     spec = rpmSpecParse(specFile, specFlags, buildRootURL);
    00446     if (spec == NULL) {
    00447         goto exit;
    00448     }
    00449
    00450     /* Check build prerequisites if necessary, unless disabled */
    00451     if (!justRm && !noDeps && checkSpec(ts, spec)) {
    00452         goto exit;
    00453     }
    00454
    00455     if (rpmSpecBuild(spec, ba)) {
    00456         goto exit;
    00457     }
    00458
    00459     if (buildMode == 't')
    00460         (void) unlink(specFile);
    00461     rc = 0;
    00462
    00463 exit:
    00464     free(specFile);
    00465     rpmSpecFree(spec);
    00466     free(buildRootURL);
    00467     return rc;
    00468 }
    00469
    00470 static int build(rpmts ts, const char * arg, BTA_t ba, const char * rcfile)
    00471 {
    00472     int rc = 0;
    00473     char * targets = argvJoin(build_targets, ",");
    00474 #define buildCleanMask  (RPMBUILD_RMSOURCE|RPMBUILD_RMSPEC)
    00475     int cleanFlags = ba->buildAmount & buildCleanMask;
    00476     rpmVSFlags vsflags, ovsflags;
    00477
    00478     vsflags = rpmExpandNumeric("%{_vsflags_build}");
    00479     if (rpmcliQueryFlags & VERIFY_DIGEST)
    00480         vsflags |= _RPMVSF_NODIGESTS;
    00481     if (rpmcliQueryFlags & VERIFY_SIGNATURE)
    00482         vsflags |= _RPMVSF_NOSIGNATURES;
    00483     if (rpmcliQueryFlags & VERIFY_HDRCHK)
    00484         vsflags |= RPMVSF_NOHDRCHK;
    00485     ovsflags = rpmtsSetVSFlags(ts, vsflags);
    00486
    00487     if (build_targets == NULL) {
    00488         rc =  buildForTarget(ts, arg, ba);
    00489         goto exit;
    00490     }
    00491
    00492     /* parse up the build operators */
    00493
    00494     printf(_("Building target platforms: %s\n"), targets);
    00495
    00496     ba->buildAmount &= ~buildCleanMask;
    00497     for (ARGV_const_t target = build_targets; target && *target; target++) {
    00498         /* Perform clean-up after last target build. */
    00499         if (*(target + 1) == NULL)
    00500             ba->buildAmount |= cleanFlags;
    00501
    00502         printf(_("Building for target %s\n"), *target);
    00503
    00504         /* Read in configuration for target. */
    00505         rpmFreeMacros(NULL);
    00506         rpmFreeRpmrc();
    00507         (void) rpmReadConfigFiles(rcfile, *target);
    00508         rc = buildForTarget(ts, arg, ba);
    00509         if (rc)
    00510             break;
    00511     }
    00512
    00513 exit:
    00514     vsflags = rpmtsSetVSFlags(ts, ovsflags);
    00515     /* Restore original configuration. */
    00516     rpmFreeMacros(NULL);
    00517     rpmFreeRpmrc();
    00518     (void) rpmReadConfigFiles(rcfile, NULL);
    00519     free(targets);
    00520
    00521     return rc;
    00522 }
    00523
    00524 int main(int argc, char *argv[])
    00525 {
    00526     rpmts ts = NULL;
    00527     enum modes bigMode = MODE_BUILD;
    00528     BTA_t ba = &rpmBTArgs;
    00529
    00530     const char *pkg = NULL;
    00531     int ec = 0;
    00532     poptContext optCon = rpmcliInit(argc, argv, optionsTable);
    00533
    00534     if (argc <= 1 || poptPeekArg(optCon) == NULL) {
    00535         printUsage(optCon, stderr, 0);
    00536         exit(EXIT_FAILURE);
    00537     }
    00538
    00539     switch (buildMode) {
    00540     case 'b':   bigMode = MODE_BUILD;           break;
    00541     case 't':   bigMode = MODE_TARBUILD;        break;
    00542     case 'B':   bigMode = MODE_REBUILD;         break;
    00543     case 'C':   bigMode = MODE_RECOMPILE;       break;
    00544     }
    00545
    00546     if (rpmcliRootDir && rpmcliRootDir[0] != '/') {
    00547         argerror(_("arguments to --root (-r) must begin with a /"));
    00548     }
    00549
    00550     /* rpmbuild is rather chatty by default */
    00551     rpmSetVerbosity(quiet ? RPMLOG_WARNING : RPMLOG_INFO);
    00552
    00553     if (rpmcliPipeOutput && initPipe())
    00554         exit(EXIT_FAILURE);
    00555
    00556     ts = rpmtsCreate();
    00557     (void) rpmtsSetRootDir(ts, rpmcliRootDir);
    00558     switch (bigMode) {
    00559     case MODE_REBUILD:
    00560     case MODE_RECOMPILE:
    00561         ba->buildAmount =
    00562             RPMBUILD_PREP | RPMBUILD_BUILD | RPMBUILD_INSTALL | RPMBUILD_CHECK;
    00563         if (bigMode == MODE_REBUILD) {
    00564             ba->buildAmount |= RPMBUILD_PACKAGEBINARY;
    00565             ba->buildAmount |= RPMBUILD_RMSOURCE;
    00566             ba->buildAmount |= RPMBUILD_RMSPEC;
    00567             ba->buildAmount |= RPMBUILD_CLEAN;
    00568             ba->buildAmount |= RPMBUILD_RMBUILD;
    00569         }
    00570
    00571         while ((pkg = poptGetArg(optCon))) {
    00572             char * specFile = NULL;
    00573
    00574             ba->cookie = NULL;
    00575             ec = rpmInstallSource(ts, pkg, &specFile, &ba->cookie);
    00576             if (ec == 0) {
    00577                 ba->rootdir = rpmcliRootDir;
    00578                 ec = build(ts, specFile, ba, rpmcliRcfile);
    00579             }
    00580             ba->cookie = _free(ba->cookie);
    00581             specFile = _free(specFile);
    00582
    00583             if (ec)
    00584                 break;
    00585         }
    00586         break;
    00587     case MODE_BUILD:
    00588     case MODE_TARBUILD:
    00589         switch (buildChar) {
    00590         case 'a':
    00591             ba->buildAmount |= RPMBUILD_PACKAGESOURCE;
    00592         case 'b':
    00593             ba->buildAmount |= RPMBUILD_PACKAGEBINARY;
    00594             ba->buildAmount |= RPMBUILD_CLEAN;
    00595             if ((buildChar == 'b') && shortCircuit)
    00596                 break;
    00597         case 'i':
    00598             ba->buildAmount |= RPMBUILD_INSTALL;
    00599             ba->buildAmount |= RPMBUILD_CHECK;
    00600             if ((buildChar == 'i') && shortCircuit)
    00601                 break;
    00602         case 'c':
    00603             ba->buildAmount |= RPMBUILD_BUILD;
    00604             if ((buildChar == 'c') && shortCircuit)
    00605                 break;
    00606         case 'p':
    00607             ba->buildAmount |= RPMBUILD_PREP;
    00608             break;
    00609
    00610         case 'l':
    00611             ba->buildAmount |= RPMBUILD_FILECHECK;
    00612             break;
    00613         case 's':
    00614             ba->buildAmount |= RPMBUILD_PACKAGESOURCE;
    00615             break;
    00616         }
    00617
    00618         while ((pkg = poptGetArg(optCon))) {
    00619             ba->rootdir = rpmcliRootDir;
    00620             ba->cookie = NULL;
    00621             ec = build(ts, pkg, ba, rpmcliRcfile);
    00622             if (ec)
    00623                 break;
    00624             rpmFreeMacros(NULL);
    00625             (void) rpmReadConfigFiles(rpmcliRcfile, NULL);
    00626         }
    00627         break;
    00628     }
    00629
    00630     ts = rpmtsFree(ts);
    00631     finishPipe();
    00632     ba->buildRootOverride = _free(ba->buildRootOverride);
    00633     build_targets = argvFree(build_targets);
    00634
    00635     rpmcliFini(optCon);
    00636
    00637     return RETVAL(ec);
    00638 }