00001
00006 #include "system.h"
00007
00008 #include <rpmio_internal.h>
00009 #include <rpmcb.h>
00010 #define _RPMTAG_INTERNAL
00011 #include <rpmbuild.h>
00012 #include "signature.h"
00013
00014 #include "debug.h"
00015
00016
00017 static int _build_debug = 0;
00018
00021 #if defined(RPM_VENDOR_OPENPKG)
00022 const char * getSourceDir(rpmfileAttrs attr, const char *filename)
00023 #else
00024 const char * getSourceDir(rpmfileAttrs attr)
00025 #endif
00026 {
00027 const char * dir = NULL;
00028 #if defined(RPM_VENDOR_OPENPKG)
00029 const char *fn;
00030
00031
00032
00033
00034 if (attr & (RPMFILE_SOURCE|RPMFILE_PATCH|RPMFILE_ICON) && filename != NULL)
00035 {
00036 fn = rpmGetPath("%{_specdir}/", filename, NULL);
00037 if (access(fn, F_OK) == 0)
00038 dir = "%{_specdir}/";
00039 fn = _free(fn);
00040 }
00041 if (dir != NULL) {
00042 } else
00043 #endif
00044 if (attr & RPMFILE_SOURCE)
00045 dir = "%{_sourcedir}/";
00046 else if (attr & RPMFILE_PATCH)
00047 dir = "%{_patchdir}/";
00048 else if (attr & RPMFILE_ICON)
00049 dir = "%{_icondir}/";
00050
00051 return dir;
00052 }
00053
00054
00055
00056
00059 static void doRmSource(Spec spec)
00060
00061
00062 {
00063 struct Source *sp;
00064 int rc;
00065
00066 #if 0
00067 rc = Unlink(spec->specFile);
00068 #endif
00069
00070 for (sp = spec->sources; sp != NULL; sp = sp->next) {
00071 const char *dn, *fn;
00072 if (sp->flags & RPMFILE_GHOST)
00073 continue;
00074 #if defined(RPM_VENDOR_OPENPKG)
00075 if (! (dn = getSourceDir(sp->flags, sp->source)))
00076 #else
00077 if (! (dn = getSourceDir(sp->flags)))
00078 #endif
00079 continue;
00080 fn = rpmGenPath(NULL, dn, sp->source);
00081 rc = Unlink(fn);
00082 fn = _free(fn);
00083 }
00084 }
00085
00086
00087
00088
00089 rpmRC doScript(Spec spec, int what, const char *name, rpmiob iob, int test)
00090 {
00091 const char * rootURL = spec->rootURL;
00092 const char * rootDir;
00093 const char * scriptName = NULL;
00094 const char * buildDirURL = rpmGenPath(rootURL, "%{_builddir}", "");
00095 const char * buildScript;
00096 const char * buildCmd = NULL;
00097 const char * buildTemplate = NULL;
00098 const char * buildPost = NULL;
00099 const char * mTemplate = NULL;
00100 const char * mCmd = NULL;
00101 const char * mPost = NULL;
00102 int argc = 0;
00103 const char **argv = NULL;
00104 FILE * fp = NULL;
00105 urlinfo u = NULL;
00106
00107 FD_t fd;
00108 FD_t xfd;
00109 pid_t pid;
00110 pid_t child;
00111 int status;
00112 rpmRC rc;
00113 size_t i;
00114
00115 switch (what) {
00116 case RPMBUILD_PREP:
00117 name = "%prep";
00118 iob = spec->prep;
00119 mTemplate = "%{__spec_prep_template}";
00120 mPost = "%{__spec_prep_post}";
00121 mCmd = "%{__spec_prep_cmd}";
00122 break;
00123 case RPMBUILD_BUILD:
00124 name = "%build";
00125 iob = spec->build;
00126 mTemplate = "%{__spec_build_template}";
00127 mPost = "%{__spec_build_post}";
00128 mCmd = "%{__spec_build_cmd}";
00129 break;
00130 case RPMBUILD_INSTALL:
00131 name = "%install";
00132 iob = spec->install;
00133 mTemplate = "%{__spec_install_template}";
00134 mPost = "%{__spec_install_post}";
00135 mCmd = "%{__spec_install_cmd}";
00136 break;
00137 case RPMBUILD_CHECK:
00138 name = "%check";
00139 iob = spec->check;
00140 mTemplate = "%{__spec_check_template}";
00141 mPost = "%{__spec_check_post}";
00142 mCmd = "%{__spec_check_cmd}";
00143 break;
00144 case RPMBUILD_CLEAN:
00145 name = "%clean";
00146 iob = spec->clean;
00147 mTemplate = "%{__spec_clean_template}";
00148 mPost = "%{__spec_clean_post}";
00149 mCmd = "%{__spec_clean_cmd}";
00150 break;
00151 case RPMBUILD_RMBUILD:
00152 name = "--clean";
00153 mTemplate = "%{__spec_clean_template}";
00154 mPost = "%{__spec_clean_post}";
00155 mCmd = "%{__spec_clean_cmd}";
00156 break;
00157
00158 case RPMBUILD_TRACK:
00159 name = "%track";
00160 iob = NULL;
00161 if (spec->foo)
00162 for (i = 0; i < spec->nfoo; i++) {
00163 if (spec->foo[i].str == NULL || spec->foo[i].iob == NULL)
00164 continue;
00165 if (xstrcasecmp(spec->foo[i].str, "track"))
00166 continue;
00167 iob = spec->foo[i].iob;
00168 break;
00169 }
00170 mTemplate = "%{__spec_track_template}";
00171 mPost = "%{__spec_track_post}";
00172 mCmd = "%{__spec_track_cmd}";
00173 break;
00174 case RPMBUILD_STRINGBUF:
00175 default:
00176 mTemplate = "%{___build_template}";
00177 mPost = "%{___build_post}";
00178 mCmd = "%{___build_cmd}";
00179 break;
00180 }
00181 if (name == NULL)
00182 name = "???";
00183
00184 if ((what != RPMBUILD_RMBUILD) && iob == NULL) {
00185 rc = RPMRC_OK;
00186 goto exit;
00187 }
00188
00189 if (rpmTempFile(rootURL, &scriptName, &fd) || fd == NULL || Ferror(fd)) {
00190 rpmlog(RPMLOG_ERR, _("Unable to open temp file.\n"));
00191 rc = RPMRC_FAIL;
00192 goto exit;
00193 }
00194
00195 if (fdGetFp(fd) == NULL)
00196 xfd = Fdopen(fd, "w.fpio");
00197 else
00198 xfd = fd;
00199
00200
00201 if ((fp = fdGetFp(xfd)) == NULL) {
00202 rc = RPMRC_FAIL;
00203 goto exit;
00204 }
00205
00206
00207 (void) urlPath(rootURL, &rootDir);
00208 if (*rootDir == '\0') rootDir = "/";
00209
00210 (void) urlPath(scriptName, &buildScript);
00211
00212 buildTemplate = rpmExpand(mTemplate, NULL);
00213 buildPost = rpmExpand(mPost, NULL);
00214
00215 (void) fputs(buildTemplate, fp);
00216
00217
00218 if (what != RPMBUILD_PREP && what != RPMBUILD_RMBUILD && spec->buildSubdir && what != RPMBUILD_TRACK)
00219 fprintf(fp, "cd '%s'\n", spec->buildSubdir);
00220
00221 if (what == RPMBUILD_RMBUILD) {
00222 if (spec->buildSubdir)
00223 fprintf(fp, "rm -rf '%s'\n", spec->buildSubdir);
00224 } else if (iob != NULL)
00225 fprintf(fp, "%s", rpmiobStr(iob));
00226
00227 (void) fputs(buildPost, fp);
00228
00229 (void) Fclose(xfd);
00230
00231 if (test) {
00232 rc = RPMRC_OK;
00233 goto exit;
00234 }
00235
00236 if (_build_debug)
00237 fprintf(stderr, "*** rootURL %s buildDirURL %s\n", rootURL, buildDirURL);
00238 if (buildDirURL && buildDirURL[0] != '/' &&
00239 (urlSplit(buildDirURL, &u) != 0)) {
00240 rc = RPMRC_FAIL;
00241 goto exit;
00242 }
00243 if (u != NULL) {
00244 switch (u->urltype) {
00245 case URL_IS_HTTPS:
00246 case URL_IS_HTTP:
00247 case URL_IS_FTP:
00248 if (_build_debug)
00249 fprintf(stderr, "*** addMacros\n");
00250 addMacro(spec->macros, "_remsh", NULL, "%{__remsh}", RMIL_SPEC);
00251 addMacro(spec->macros, "_remhost", NULL, u->host, RMIL_SPEC);
00252 if (strcmp(rootDir, "/"))
00253 addMacro(spec->macros, "_remroot", NULL, rootDir, RMIL_SPEC);
00254 break;
00255 case URL_IS_UNKNOWN:
00256 case URL_IS_DASH:
00257 case URL_IS_PATH:
00258 case URL_IS_HKP:
00259 default:
00260 break;
00261 }
00262 }
00263
00264 buildCmd = rpmExpand(mCmd, " ", buildScript, NULL);
00265 (void) poptParseArgvString(buildCmd, &argc, &argv);
00266
00267 if (what != RPMBUILD_TRACK)
00268 rpmlog(RPMLOG_NOTICE, _("Executing(%s): %s\n"), name, buildCmd);
00269 if (!(child = fork())) {
00270
00271
00272 errno = 0;
00273
00274 (void) execvp(argv[0], (char *const *)argv);
00275
00276 rpmlog(RPMLOG_ERR, _("Exec of %s failed (%s): %s\n"),
00277 scriptName, name, strerror(errno));
00278
00279 _exit(-1);
00280 }
00281
00282 pid = waitpid(child, &status, 0);
00283
00284 if (!WIFEXITED(status) || WEXITSTATUS(status)) {
00285 rpmlog(RPMLOG_ERR, _("Bad exit status from %s (%s)\n"),
00286 scriptName, name);
00287 rc = RPMRC_FAIL;
00288 } else
00289 rc = RPMRC_OK;
00290
00291 exit:
00292 if (scriptName) {
00293 #if defined(RPM_VENDOR_OPENPKG)
00294
00295
00296
00297
00298
00299 #else
00300 if (rc == RPMRC_OK)
00301 #endif
00302 (void) Unlink(scriptName);
00303 scriptName = _free(scriptName);
00304 }
00305 if (u != NULL) {
00306 switch (u->urltype) {
00307 case URL_IS_HTTPS:
00308 case URL_IS_HTTP:
00309 case URL_IS_FTP:
00310 if (_build_debug)
00311 fprintf(stderr, "*** delMacros\n");
00312 delMacro(spec->macros, "_remsh");
00313 delMacro(spec->macros, "_remhost");
00314 if (strcmp(rootDir, "/"))
00315 delMacro(spec->macros, "_remroot");
00316 break;
00317 case URL_IS_UNKNOWN:
00318 case URL_IS_DASH:
00319 case URL_IS_PATH:
00320 case URL_IS_HKP:
00321 default:
00322 break;
00323 }
00324 }
00325 argv = _free(argv);
00326 buildCmd = _free(buildCmd);
00327 buildTemplate = _free(buildTemplate);
00328 buildPost = _free(buildPost);
00329 buildDirURL = _free(buildDirURL);
00330
00331 return rc;
00332 }
00333
00334 rpmRC buildSpec(rpmts ts, Spec spec, int what, int test)
00335 {
00336 rpmRC rc = RPMRC_OK;
00337
00338 if (!spec->recursing && spec->BACount) {
00339 int x;
00340
00341
00342 if (spec->BASpecs != NULL)
00343 for (x = 0; x < spec->BACount; x++) {
00344 if ((rc = buildSpec(ts, spec->BASpecs[x],
00345 (what & ~RPMBUILD_RMSOURCE) |
00346 (x ? 0 : (what & RPMBUILD_PACKAGESOURCE)),
00347 test))) {
00348 goto exit;
00349 }
00350 }
00351 } else {
00352
00353 if ((what & RPMBUILD_TRACK) &&
00354 (rc = doScript(spec, RPMBUILD_TRACK, NULL, NULL, test)))
00355 goto exit;
00356
00357 if ((what & RPMBUILD_PREP) &&
00358 (rc = doScript(spec, RPMBUILD_PREP, NULL, NULL, test)))
00359 goto exit;
00360
00361 if ((what & RPMBUILD_BUILD) &&
00362 (rc = doScript(spec, RPMBUILD_BUILD, NULL, NULL, test)))
00363 goto exit;
00364
00365 if ((what & RPMBUILD_INSTALL) &&
00366 (rc = doScript(spec, RPMBUILD_INSTALL, NULL, NULL, test)))
00367 goto exit;
00368
00369 if ((what & RPMBUILD_CHECK) &&
00370 (rc = doScript(spec, RPMBUILD_CHECK, NULL, NULL, test)))
00371 goto exit;
00372
00373 if ((what & RPMBUILD_PACKAGESOURCE) &&
00374 (rc = processSourceFiles(spec)))
00375 goto exit;
00376
00377 if (((what & RPMBUILD_INSTALL) || (what & RPMBUILD_PACKAGEBINARY) ||
00378 (what & RPMBUILD_FILECHECK)) &&
00379 (rc = processBinaryFiles(spec, what & RPMBUILD_INSTALL, test)))
00380 goto exit;
00381
00382 if (((what & RPMBUILD_PACKAGESOURCE) && !test) &&
00383 (rc = packageSources(spec)))
00384 return rc;
00385
00386 if (((what & RPMBUILD_PACKAGEBINARY) && !test) &&
00387 (rc = packageBinaries(spec)))
00388 goto exit;
00389
00390 if ((what & RPMBUILD_CLEAN) &&
00391 (rc = doScript(spec, RPMBUILD_CLEAN, NULL, NULL, test)))
00392 goto exit;
00393
00394 if ((what & RPMBUILD_RMBUILD) &&
00395 (rc = doScript(spec, RPMBUILD_RMBUILD, NULL, NULL, test)))
00396 goto exit;
00397 }
00398
00399 if (what & RPMBUILD_RMSOURCE)
00400 doRmSource(spec);
00401
00402 if (what & RPMBUILD_RMSPEC)
00403 (void) Unlink(spec->specFile);
00404
00405 #if defined(RPM_VENDOR_OPENPKG)
00406
00407
00408
00409
00410
00411
00412
00413 if (what & RPMBUILD_RMSOURCE) {
00414 const char *pn;
00415 pn = rpmGetPath("%{_sourcedir}", NULL);
00416 Rmdir(pn);
00417 pn = _free(pn);
00418 }
00419 if (what & RPMBUILD_RMSPEC) {
00420 const char *pn;
00421 pn = rpmGetPath("%{_specdir}", NULL);
00422 Rmdir(pn);
00423 pn = _free(pn);
00424 }
00425 #endif
00426
00427 exit:
00428 if (rc != RPMRC_OK && rpmlogGetNrecs() > 0) {
00429 rpmlog(RPMLOG_NOTICE, _("\n\nRPM build errors:\n"));
00430 rpmlogPrint(NULL);
00431 }
00432
00433 return rc;
00434 }