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 if ( rpm_close_all() ) {
00214 perror( "rpm_close_all" );
00215 _exit( -1 );
00216 }
00217
00218
00219 {
00220 const char *const name[] = {
00221 "LANG",
00222 "LANGUAGE",
00223 "LC_CTYPE",
00224 "LC_NUMERIC",
00225 "LC_TIME",
00226 "LC_COLLATE",
00227 "LC_MONETARY",
00228 "LC_MESSAGES",
00229 "LC_PAPER",
00230 "LC_NAME",
00231 "LC_ADDRESS",
00232 "LC_TELEPHONE",
00233 "LC_MEASUREMENT",
00234 "LC_IDENTIFICATION",
00235 "LC_ALL",
00236 0
00237 };
00238 unsigned int i;
00239
00240 for (i = 0; name[i]; ++i)
00241 unsetenv (name[i]);
00242 }
00243
00244
00245 errno = 0;
00246
00247 (void) execvp(argv[0], (char *const *)argv);
00248
00249 rpmError(RPMERR_SCRIPT, _("Exec of %s failed (%s): %s\n"),
00250 scriptName, name, strerror(errno));
00251
00252 _exit(-1);
00253 }
00254
00255 rc = waitpid(child, &status, 0);
00256
00257 if (!WIFEXITED(status) || WEXITSTATUS(status)) {
00258 rpmError(RPMERR_SCRIPT, _("Bad exit status from %s (%s)\n"),
00259 scriptName, name);
00260 rc = RPMERR_SCRIPT;
00261 } else
00262 rc = 0;
00263
00264 exit:
00265 if (scriptName) {
00266 if (!rc)
00267 (void) Unlink(scriptName);
00268 scriptName = _free(scriptName);
00269 }
00270 if (u != NULL) {
00271 switch (u->urltype) {
00272 case URL_IS_FTP:
00273 case URL_IS_HTTP:
00274 if (_build_debug)
00275 fprintf(stderr, "*** delMacros\n");
00276 delMacro(spec->macros, "_remsh");
00277 delMacro(spec->macros, "_remhost");
00278 if (strcmp(rootDir, "/"))
00279 delMacro(spec->macros, "_remroot");
00280 break;
00281 default:
00282 break;
00283 }
00284 }
00285 argv = _free(argv);
00286 buildCmd = _free(buildCmd);
00287 buildTemplate = _free(buildTemplate);
00288 buildPost = _free(buildPost);
00289 buildDirURL = _free(buildDirURL);
00290
00291 return rc;
00292 }
00293
00294 int buildSpec(Spec spec, int what, int test)
00295 {
00296 int rc = 0;
00297
00298 if (!spec->recursing && spec->BACount) {
00299 int x;
00300
00301
00302 if (spec->BASpecs != NULL)
00303 for (x = 0; x < spec->BACount; x++) {
00304 if ((rc = buildSpec(spec->BASpecs[x],
00305 (what & ~RPMBUILD_RMSOURCE) |
00306 (x ? 0 : (what & RPMBUILD_PACKAGESOURCE)),
00307 test))) {
00308 goto exit;
00309 }
00310 }
00311 } else {
00312 if ((what & RPMBUILD_PREP) &&
00313 (rc = doScript(spec, RPMBUILD_PREP, NULL, NULL, test)))
00314 goto exit;
00315
00316 if ((what & RPMBUILD_BUILD) &&
00317 (rc = doScript(spec, RPMBUILD_BUILD, NULL, NULL, test)))
00318 goto exit;
00319
00320 if ((what & RPMBUILD_INSTALL) &&
00321 (rc = doScript(spec, RPMBUILD_INSTALL, NULL, NULL, test)))
00322 goto exit;
00323
00324 if ((what & RPMBUILD_PACKAGESOURCE) &&
00325 (rc = processSourceFiles(spec)))
00326 goto exit;
00327
00328 if (((what & RPMBUILD_INSTALL) || (what & RPMBUILD_PACKAGEBINARY) ||
00329 (what & RPMBUILD_FILECHECK)) &&
00330 (rc = processBinaryFiles(spec, what & RPMBUILD_INSTALL, test)))
00331 goto exit;
00332
00333 if (((what & RPMBUILD_PACKAGESOURCE) && !test) &&
00334 (rc = packageSources(spec)))
00335 return rc;
00336
00337 if (((what & RPMBUILD_PACKAGEBINARY) && !test) &&
00338 (rc = packageBinaries(spec)))
00339 goto exit;
00340
00341 if ((what & RPMBUILD_CLEAN) &&
00342 (rc = doScript(spec, RPMBUILD_CLEAN, NULL, NULL, test)))
00343 goto exit;
00344
00345 if ((what & RPMBUILD_RMBUILD) &&
00346 (rc = doScript(spec, RPMBUILD_RMBUILD, NULL, NULL, test)))
00347 goto exit;
00348 }
00349
00350 if (what & RPMBUILD_RMSOURCE)
00351 doRmSource(spec);
00352
00353 if (what & RPMBUILD_RMSPEC)
00354 (void) Unlink(spec->specFile);
00355
00356 exit:
00357 if (rc && rpmlogGetNrecs() > 0) {
00358 rpmMessage(RPMMESS_NORMAL, _("\n\nRPM build errors:\n"));
00359 rpmlogPrint(NULL);
00360 }
00361
00362 return rc;
00363 }