00001
00006 #include "system.h"
00007
00008 #include <rpmio_internal.h>
00009 #include <rpmbuild.h>
00010
00011 #include "debug.h"
00012
00013
00014 static int _build_debug = 0;
00015
00016
00017
00018
00019
00022 static void doRmSource(Spec spec)
00023
00024
00025
00026 {
00027 struct Source *p;
00028 Package pkg;
00029 int rc;
00030
00031 #if 0
00032 rc = Unlink(spec->specFile);
00033 #endif
00034
00035 for (p = spec->sources; p != NULL; p = p->next) {
00036 if (! (p->flags & RPMBUILD_ISNO)) {
00037 const char *fn = rpmGetPath("%{_sourcedir}/", p->source, NULL);
00038 rc = Unlink(fn);
00039 fn = _free(fn);
00040 }
00041 }
00042
00043 for (pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
00044 for (p = pkg->icon; p != NULL; p = p->next) {
00045 if (! (p->flags & RPMBUILD_ISNO)) {
00046 const char *fn = rpmGetPath("%{_sourcedir}/", p->source, NULL);
00047 rc = Unlink(fn);
00048 fn = _free(fn);
00049 }
00050 }
00051 }
00052 }
00053
00054
00055
00056
00057 int doScript(Spec spec, int what, const char *name, StringBuf sb, int test)
00058 {
00059 const char * rootURL = spec->rootURL;
00060 const char * rootDir;
00061 const char *scriptName = NULL;
00062 const char * buildDirURL = rpmGenPath(rootURL, "%{_builddir}", "");
00063 const char * buildScript;
00064 const char * buildCmd = NULL;
00065 const char * buildTemplate = NULL;
00066 const char * buildPost = NULL;
00067 const char * mTemplate = NULL;
00068 const char * mPost = NULL;
00069 int argc = 0;
00070 const char **argv = NULL;
00071 FILE * fp = NULL;
00072 urlinfo u = NULL;
00073
00074 FD_t fd;
00075 FD_t xfd;
00076 int child;
00077 int status;
00078 int rc;
00079
00080
00081 switch (what) {
00082 case RPMBUILD_PREP:
00083 name = "%prep";
00084 sb = spec->prep;
00085 mTemplate = "%{__spec_prep_template}";
00086 mPost = "%{__spec_prep_post}";
00087 break;
00088 case RPMBUILD_BUILD:
00089 name = "%build";
00090 sb = spec->build;
00091 mTemplate = "%{__spec_build_template}";
00092 mPost = "%{__spec_build_post}";
00093 break;
00094 case RPMBUILD_INSTALL:
00095 name = "%install";
00096 sb = spec->install;
00097 mTemplate = "%{__spec_install_template}";
00098 mPost = "%{__spec_install_post}";
00099 break;
00100 case RPMBUILD_CLEAN:
00101 name = "%clean";
00102 sb = spec->clean;
00103 mTemplate = "%{__spec_clean_template}";
00104 mPost = "%{__spec_clean_post}";
00105 break;
00106 case RPMBUILD_RMBUILD:
00107 name = "--clean";
00108 mTemplate = "%{__spec_clean_template}";
00109 mPost = "%{__spec_clean_post}";
00110 break;
00111 case RPMBUILD_STRINGBUF:
00112 default:
00113 mTemplate = "%{___build_template}";
00114 mPost = "%{___build_post}";
00115 break;
00116 }
00117
00118
00119 if ((what != RPMBUILD_RMBUILD) && sb == NULL) {
00120 rc = 0;
00121 goto exit;
00122 }
00123
00124 if (makeTempFile(rootURL, &scriptName, &fd) || fd == NULL || Ferror(fd)) {
00125 rpmError(RPMERR_SCRIPT, _("Unable to open temp file.\n"));
00126 rc = RPMERR_SCRIPT;
00127 goto exit;
00128 }
00129
00130 #ifdef HAVE_FCHMOD
00131 switch (rootut) {
00132 case URL_IS_PATH:
00133 case URL_IS_UNKNOWN:
00134 (void)fchmod(Fileno(fd), 0600);
00135 break;
00136 default:
00137 break;
00138 }
00139 #endif
00140
00141
00142 if (fdGetFp(fd) == NULL)
00143 xfd = Fdopen(fd, "w.fpio");
00144 else
00145 xfd = fd;
00146
00147
00148
00149 if ((fp = fdGetFp(xfd)) == NULL) {
00150 rc = RPMERR_SCRIPT;
00151 goto exit;
00152 }
00153
00154
00155 (void) urlPath(rootURL, &rootDir);
00156
00157 if (*rootDir == '\0') rootDir = "/";
00158
00159
00160 (void) urlPath(scriptName, &buildScript);
00161
00162 buildTemplate = rpmExpand(mTemplate, NULL);
00163 buildPost = rpmExpand(mPost, NULL);
00164
00165 (void) fputs(buildTemplate, fp);
00166
00167 if (what != RPMBUILD_PREP && what != RPMBUILD_RMBUILD && spec->buildSubdir)
00168 fprintf(fp, "cd %s\n", spec->buildSubdir);
00169
00170 if (what == RPMBUILD_RMBUILD) {
00171 if (spec->buildSubdir)
00172 fprintf(fp, "rm -rf %s\n", spec->buildSubdir);
00173 } else
00174 fprintf(fp, "%s", getStringBuf(sb));
00175
00176 (void) fputs(buildPost, fp);
00177
00178 (void) Fclose(xfd);
00179
00180 if (test) {
00181 rc = 0;
00182 goto exit;
00183 }
00184
00185 if (_build_debug)
00186 fprintf(stderr, "*** rootURL %s buildDirURL %s\n", rootURL, buildDirURL);
00187 if (buildDirURL && buildDirURL[0] != '/' &&
00188 (urlSplit(buildDirURL, &u) != 0)) {
00189 rc = RPMERR_SCRIPT;
00190 goto exit;
00191 }
00192 if (u != NULL) {
00193 switch (u->urltype) {
00194 case URL_IS_FTP:
00195 if (_build_debug)
00196 fprintf(stderr, "*** addMacros\n");
00197 addMacro(spec->macros, "_remsh", NULL, "%{__remsh}", RMIL_SPEC);
00198 addMacro(spec->macros, "_remhost", NULL, u->host, RMIL_SPEC);
00199 if (strcmp(rootDir, "/"))
00200 addMacro(spec->macros, "_remroot", NULL, rootDir, RMIL_SPEC);
00201 break;
00202 case URL_IS_HTTP:
00203 default:
00204 break;
00205 }
00206 }
00207
00208 buildCmd = rpmExpand("%{___build_cmd}", " ", buildScript, NULL);
00209 (void) poptParseArgvString(buildCmd, &argc, &argv);
00210
00211 rpmMessage(RPMMESS_NORMAL, _("Executing(%s): %s\n"), name, buildCmd);
00212 if (!(child = fork())) {
00213
00214
00215 errno = 0;
00216
00217 (void) execvp(argv[0], (char *const *)argv);
00218
00219 rpmError(RPMERR_SCRIPT, _("Exec of %s failed (%s): %s\n"),
00220 scriptName, name, strerror(errno));
00221
00222 _exit(-1);
00223 }
00224
00225 rc = waitpid(child, &status, 0);
00226
00227 if (!WIFEXITED(status) || WEXITSTATUS(status)) {
00228 rpmError(RPMERR_SCRIPT, _("Bad exit status from %s (%s)\n"),
00229 scriptName, name);
00230 rc = RPMERR_SCRIPT;
00231 } else
00232 rc = 0;
00233
00234 exit:
00235 if (scriptName) {
00236 if (!rc)
00237 (void) Unlink(scriptName);
00238 scriptName = _free(scriptName);
00239 }
00240 if (u != NULL) {
00241 switch (u->urltype) {
00242 case URL_IS_FTP:
00243 case URL_IS_HTTP:
00244 if (_build_debug)
00245 fprintf(stderr, "*** delMacros\n");
00246 delMacro(spec->macros, "_remsh");
00247 delMacro(spec->macros, "_remhost");
00248 if (strcmp(rootDir, "/"))
00249 delMacro(spec->macros, "_remroot");
00250 break;
00251 default:
00252 break;
00253 }
00254 }
00255 argv = _free(argv);
00256 buildCmd = _free(buildCmd);
00257 buildTemplate = _free(buildTemplate);
00258 buildPost = _free(buildPost);
00259 buildDirURL = _free(buildDirURL);
00260
00261 return rc;
00262 }
00263
00264 int buildSpec(Spec spec, int what, int test)
00265 {
00266 int rc = 0;
00267
00268 if (!spec->recursing && spec->BACount) {
00269 int x;
00270
00271
00272 if (spec->BASpecs != NULL)
00273 for (x = 0; x < spec->BACount; x++) {
00274 if ((rc = buildSpec(spec->BASpecs[x],
00275 (what & ~RPMBUILD_RMSOURCE) |
00276 (x ? 0 : (what & RPMBUILD_PACKAGESOURCE)),
00277 test))) {
00278 goto exit;
00279 }
00280 }
00281 } else {
00282 if ((what & RPMBUILD_PREP) &&
00283 (rc = doScript(spec, RPMBUILD_PREP, NULL, NULL, test)))
00284 goto exit;
00285
00286 if ((what & RPMBUILD_BUILD) &&
00287 (rc = doScript(spec, RPMBUILD_BUILD, NULL, NULL, test)))
00288 goto exit;
00289
00290 if ((what & RPMBUILD_INSTALL) &&
00291 (rc = doScript(spec, RPMBUILD_INSTALL, NULL, NULL, test)))
00292 goto exit;
00293
00294 if ((what & RPMBUILD_PACKAGESOURCE) &&
00295 (rc = processSourceFiles(spec)))
00296 goto exit;
00297
00298 if (((what & RPMBUILD_INSTALL) || (what & RPMBUILD_PACKAGEBINARY) ||
00299 (what & RPMBUILD_FILECHECK)) &&
00300 (rc = processBinaryFiles(spec, what & RPMBUILD_INSTALL, test)))
00301 goto exit;
00302
00303 if (((what & RPMBUILD_PACKAGESOURCE) && !test) &&
00304 (rc = packageSources(spec)))
00305 return rc;
00306
00307 if (((what & RPMBUILD_PACKAGEBINARY) && !test) &&
00308 (rc = packageBinaries(spec)))
00309 goto exit;
00310
00311 if ((what & RPMBUILD_CLEAN) &&
00312 (rc = doScript(spec, RPMBUILD_CLEAN, NULL, NULL, test)))
00313 goto exit;
00314
00315 if ((what & RPMBUILD_RMBUILD) &&
00316 (rc = doScript(spec, RPMBUILD_RMBUILD, NULL, NULL, test)))
00317 goto exit;
00318 }
00319
00320 if (what & RPMBUILD_RMSOURCE)
00321 doRmSource(spec);
00322
00323 if (what & RPMBUILD_RMSPEC)
00324 (void) Unlink(spec->specFile);
00325
00326 exit:
00327 if (rc && rpmlogGetNrecs() > 0) {
00328 rpmMessage(RPMMESS_NORMAL, _("\n\nRPM build errors:\n"));
00329 rpmlogPrint(NULL);
00330 }
00331
00332 return rc;
00333 }