rpm 5.2.1
|
00001 00006 #include "system.h" 00007 00008 #include <rpmio.h> 00009 #include <rpmiotypes.h> 00010 #include <argv.h> 00011 #include <rpmcb.h> 00012 #include <rpmurl.h> 00013 #ifdef NOTYET 00014 #include <rpmmg.h> 00015 #endif 00016 00017 #include <rpmbuild.h> 00018 00019 #include "misc.h" /* XXX rpmMkdirPath */ 00020 #include "debug.h" 00021 00022 /* These have to be global to make up for stupid compilers */ 00023 /*@unchecked@*/ 00024 static int leaveDirs, skipDefaultAction; 00025 /*@unchecked@*/ 00026 static int createDir, quietly; 00027 /*@unchecked@*/ /*@observer@*/ /*@null@*/ 00028 static const char * dirName = NULL; 00029 /*@unchecked@*/ /*@observer@*/ 00030 static struct poptOption optionsTable[] = { 00031 { NULL, 'a', POPT_ARG_STRING, NULL, 'a', NULL, NULL}, 00032 { NULL, 'b', POPT_ARG_STRING, NULL, 'b', NULL, NULL}, 00033 { NULL, 'c', 0, &createDir, 0, NULL, NULL}, 00034 { NULL, 'D', 0, &leaveDirs, 0, NULL, NULL}, 00035 { NULL, 'n', POPT_ARG_STRING, &dirName, 0, NULL, NULL}, 00036 { NULL, 'T', 0, &skipDefaultAction, 0, NULL, NULL}, 00037 { NULL, 'q', 0, &quietly, 0, NULL, NULL}, 00038 { 0, 0, 0, 0, 0, NULL, NULL} 00039 }; 00040 00046 static rpmRC checkOwners(const char * urlfn) 00047 /*@globals h_errno, fileSystem, internalState @*/ 00048 /*@modifies fileSystem, internalState @*/ 00049 { 00050 struct stat sb; 00051 00052 if (Lstat(urlfn, &sb)) { 00053 rpmlog(RPMLOG_ERR, _("Bad source: %s: %s\n"), 00054 urlfn, strerror(errno)); 00055 return RPMRC_FAIL; 00056 } 00057 if (!getUname(sb.st_uid) || !getGname(sb.st_gid)) { 00058 rpmlog(RPMLOG_ERR, _("Bad owner/group: %s\n"), urlfn); 00059 return RPMRC_FAIL; 00060 } 00061 00062 return RPMRC_OK; 00063 } 00064 00065 #ifndef DYING 00066 00078 /*@observer@*/ 00079 static char *doPatch(Spec spec, rpmuint32_t c, int strip, const char *db, 00080 int reverse, int removeEmpties, int fuzz, const char *subdir) 00081 /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/ 00082 /*@modifies rpmGlobalMacroContext, fileSystem, internalState @*/ 00083 { 00084 const char *fn, *Lurlfn; 00085 static char buf[BUFSIZ]; 00086 char args[BUFSIZ], *t = args; 00087 struct Source *sp; 00088 rpmCompressedMagic compressed = COMPRESSED_NOT; 00089 int urltype; 00090 const char *patch, *flags; 00091 00092 *t = '\0'; 00093 if (db) 00094 t = stpcpy( stpcpy(t, "-b --suffix "), db); 00095 #if defined(RPM_VENDOR_OPENPKG) /* always-backup-on-patching */ 00096 /* always create backup files in OpenPKG */ 00097 else 00098 t = stpcpy(t, "-b --suffix .orig "); 00099 #endif 00100 if (subdir) 00101 t = stpcpy( stpcpy(t, "-d "), subdir); 00102 if (fuzz >= 0) { 00103 t = stpcpy(t, "-F "); 00104 sprintf(t, "%10.10d", fuzz); 00105 t += strlen(t); 00106 } 00107 if (reverse) 00108 t = stpcpy(t, " -R"); 00109 if (removeEmpties) 00110 t = stpcpy(t, " -E"); 00111 00112 for (sp = spec->sources; sp != NULL; sp = sp->next) { 00113 if ((sp->flags & RPMFILE_PATCH) && (sp->num == c)) 00114 break; 00115 } 00116 if (sp == NULL) { 00117 rpmlog(RPMLOG_ERR, _("No patch number %d\n"), c); 00118 return NULL; 00119 } 00120 00121 Lurlfn = rpmGenPath(NULL, "%{_patchdir}/", sp->source); 00122 00123 /* XXX On non-build parse's, file cannot be stat'd or read */ 00124 if (!spec->force && (isCompressed(Lurlfn, &compressed) || checkOwners(Lurlfn))) { 00125 Lurlfn = _free(Lurlfn); 00126 return NULL; 00127 } 00128 00129 fn = NULL; 00130 urltype = urlPath(Lurlfn, &fn); 00131 switch (urltype) { 00132 case URL_IS_HTTPS: /* XXX WRONG WRONG WRONG */ 00133 case URL_IS_HTTP: /* XXX WRONG WRONG WRONG */ 00134 case URL_IS_FTP: /* XXX WRONG WRONG WRONG */ 00135 case URL_IS_HKP: /* XXX WRONG WRONG WRONG */ 00136 case URL_IS_PATH: 00137 case URL_IS_UNKNOWN: 00138 break; 00139 case URL_IS_DASH: 00140 Lurlfn = _free(Lurlfn); 00141 return NULL; 00142 /*@notreached@*/ break; 00143 } 00144 00145 patch = rpmGetPath("%{__patch}", NULL); 00146 if (strcmp(patch, "%{__patch}") == 0) 00147 patch = xstrdup("patch"); 00148 00149 flags = rpmExpand("%{?_default_patch_flags}%{!?_default_patch_flags:-s}", NULL); 00150 00151 if (compressed) { 00152 const char *zipper; 00153 00154 switch (compressed) { 00155 default: 00156 case COMPRESSED_NOT: /* XXX can't happen */ 00157 case COMPRESSED_OTHER: 00158 case COMPRESSED_ZIP: /* XXX wrong */ 00159 zipper = "%{__gzip}"; 00160 break; 00161 case COMPRESSED_BZIP2: 00162 zipper = "%{__bzip2}"; 00163 break; 00164 case COMPRESSED_LZOP: 00165 zipper = "%{__lzop}"; 00166 break; 00167 case COMPRESSED_LZMA: 00168 zipper = "%{__lzma}"; 00169 break; 00170 case COMPRESSED_XZ: 00171 zipper = "%{__xz}"; 00172 break; 00173 } 00174 zipper = rpmGetPath(zipper, NULL); 00175 00176 sprintf(buf, 00177 "echo \"Patch #%d (%s):\"\n" 00178 "%s -d < '%s' | %s -p%d %s %s\n" 00179 "STATUS=$?\n" 00180 "if [ $STATUS -ne 0 ]; then\n" 00181 " exit $STATUS\n" 00182 "fi", 00183 c, 00184 /*@-moduncon@*/ 00185 (const char *) basename((char *)fn), 00186 /*@=moduncon@*/ 00187 zipper, 00188 fn, patch, strip, args, flags); 00189 zipper = _free(zipper); 00190 } else { 00191 sprintf(buf, 00192 "echo \"Patch #%d (%s):\"\n" 00193 "%s -p%d %s %s < '%s'", c, 00194 /*@-moduncon@*/ 00195 (const char *) basename((char *)fn), 00196 /*@=moduncon@*/ 00197 patch, strip, args, flags, fn); 00198 } 00199 00200 patch = _free(patch); 00201 flags = _free(flags); 00202 Lurlfn = _free(Lurlfn); 00203 return buf; 00204 } 00205 #endif 00206 00214 /*@observer@*/ 00215 static const char *doUntar(Spec spec, rpmuint32_t c, int quietly) 00216 /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/ 00217 /*@modifies rpmGlobalMacroContext, fileSystem, internalState @*/ 00218 { 00219 const char *fn, *Lurlfn; 00220 static char buf[BUFSIZ]; 00221 char *taropts; 00222 char *t = NULL; 00223 struct Source *sp; 00224 rpmCompressedMagic compressed = COMPRESSED_NOT; 00225 int urltype; 00226 const char *tar; 00227 00228 for (sp = spec->sources; sp != NULL; sp = sp->next) { 00229 if ((sp->flags & RPMFILE_SOURCE) && (sp->num == c)) { 00230 break; 00231 } 00232 } 00233 if (sp == NULL) { 00234 rpmlog(RPMLOG_ERR, _("No source number %d\n"), c); 00235 return NULL; 00236 } 00237 00238 /*@-internalglobs@*/ /* FIX: shrug */ 00239 taropts = ((rpmIsVerbose() && !quietly) ? "-xvvf" : "-xf"); 00240 /*@=internalglobs@*/ 00241 00242 #if defined(RPM_VENDOR_OPENPKG) /* splitted-source-directory */ 00243 Lurlfn = rpmGenPath(NULL, getSourceDir(sp->flags, sp->source), sp->source); 00244 #else 00245 Lurlfn = rpmGenPath(NULL, getSourceDir(sp->flags), sp->source); 00246 #endif 00247 00248 /* XXX On non-build parse's, file cannot be stat'd or read */ 00249 if (!spec->force && (isCompressed(Lurlfn, &compressed) || checkOwners(Lurlfn))) { 00250 Lurlfn = _free(Lurlfn); 00251 return NULL; 00252 } 00253 00254 fn = NULL; 00255 urltype = urlPath(Lurlfn, &fn); 00256 switch (urltype) { 00257 case URL_IS_HTTPS: /* XXX WRONG WRONG WRONG */ 00258 case URL_IS_HTTP: /* XXX WRONG WRONG WRONG */ 00259 case URL_IS_FTP: /* XXX WRONG WRONG WRONG */ 00260 case URL_IS_HKP: /* XXX WRONG WRONG WRONG */ 00261 case URL_IS_PATH: 00262 case URL_IS_UNKNOWN: 00263 break; 00264 case URL_IS_DASH: 00265 Lurlfn = _free(Lurlfn); 00266 return NULL; 00267 /*@notreached@*/ break; 00268 } 00269 #ifdef NOTYET 00270 { rpmmg mg; 00271 00272 _rpmmg_debug = 1; 00273 mg = rpmmgNew(NULL, 0); 00274 t = (char *) rpmmgFile(mg, fn); 00275 mg = rpmmgFree(mg); 00276 fprintf(stderr, "==> %s: %s\n", fn, t); 00277 t = _free(t); 00278 _rpmmg_debug = 0; 00279 } 00280 #endif 00281 00282 tar = rpmGetPath("%{__tar}", NULL); 00283 if (strcmp(tar, "%{__tar}") == 0) 00284 tar = xstrdup("tar"); 00285 00286 #if defined(RPM_VENDOR_ARK) /* use-gnu-tar-compression-detection */ 00287 /* We leave compression handling for all tar based files up to GNU tar */ 00288 if (compressed == COMPRESSED_ZIP) 00289 #else 00290 if (compressed != COMPRESSED_NOT) 00291 #endif 00292 { 00293 const char *zipper; 00294 int needtar = 1; 00295 00296 switch (compressed) { 00297 case COMPRESSED_NOT: /* XXX can't happen */ 00298 case COMPRESSED_OTHER: 00299 t = "%{__gzip} -dc"; 00300 break; 00301 case COMPRESSED_BZIP2: 00302 t = "%{__bzip2} -dc"; 00303 break; 00304 case COMPRESSED_LZOP: 00305 t = "%{__lzop} -dc"; 00306 break; 00307 case COMPRESSED_LZMA: 00308 t = "%{__lzma} -dc"; 00309 break; 00310 case COMPRESSED_XZ: 00311 t = "%{__xz} -dc"; 00312 break; 00313 case COMPRESSED_ZIP: 00314 #if defined(RPM_VENDOR_OPENPKG) /* use-bsdtar-for-zip-files */ 00315 t = "%{__bsdtar} -x -f"; 00316 #else 00317 if (rpmIsVerbose() && !quietly) 00318 t = "%{__unzip}"; 00319 else 00320 t = "%{__unzip} -qq"; 00321 #endif 00322 needtar = 0; 00323 break; 00324 } 00325 zipper = rpmGetPath(t, NULL); 00326 buf[0] = '\0'; 00327 t = stpcpy(buf, zipper); 00328 zipper = _free(zipper); 00329 *t++ = ' '; 00330 *t++ = '\''; 00331 t = stpcpy(t, fn); 00332 *t++ = '\''; 00333 if (needtar) { 00334 t = stpcpy(t, " | "); 00335 t = stpcpy(t, tar); 00336 t = stpcpy(t, " "); 00337 t = stpcpy(t, taropts); 00338 t = stpcpy(t, " -"); 00339 } 00340 t = stpcpy(t, 00341 "\n" 00342 "STATUS=$?\n" 00343 "if [ $STATUS -ne 0 ]; then\n" 00344 " exit $STATUS\n" 00345 "fi"); 00346 } else { 00347 buf[0] = '\0'; 00348 t = stpcpy(buf, tar); 00349 t = stpcpy(t, " "); 00350 t = stpcpy(t, taropts); 00351 *t++ = ' '; 00352 t = stpcpy(t, fn); 00353 } 00354 00355 tar = _free(tar); 00356 Lurlfn = _free(Lurlfn); 00357 return buf; 00358 } 00359 00367 static int doSetupMacro(Spec spec, const char * line) 00368 /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/ 00369 /*@modifies spec->buildSubdir, spec->macros, spec->prep, 00370 spec->packages->header, 00371 rpmGlobalMacroContext, fileSystem, internalState @*/ 00372 { 00373 char buf[BUFSIZ]; 00374 rpmiob before; 00375 rpmiob after; 00376 poptContext optCon; 00377 int argc; 00378 const char ** argv; 00379 int arg; 00380 const char * optArg; 00381 int rc; 00382 rpmuint32_t num; 00383 00384 /*@-mods@*/ 00385 leaveDirs = skipDefaultAction = 0; 00386 createDir = quietly = 0; 00387 dirName = NULL; 00388 /*@=mods@*/ 00389 00390 if ((rc = poptParseArgvString(line, &argc, &argv))) { 00391 rpmlog(RPMLOG_ERR, _("Error parsing %%setup: %s\n"), 00392 poptStrerror(rc)); 00393 return RPMRC_FAIL; 00394 } 00395 00396 before = rpmiobNew(0); 00397 after = rpmiobNew(0); 00398 00399 optCon = poptGetContext(NULL, argc, argv, optionsTable, 0); 00400 while ((arg = poptGetNextOpt(optCon)) > 0) { 00401 optArg = poptGetOptArg(optCon); 00402 00403 /* We only parse -a and -b here */ 00404 00405 if (parseNum(optArg, &num)) { 00406 rpmlog(RPMLOG_ERR, _("line %d: Bad arg to %%setup: %s\n"), 00407 spec->lineNum, (optArg ? optArg : "???")); 00408 before = rpmiobFree(before); 00409 after = rpmiobFree(after); 00410 optCon = poptFreeContext(optCon); 00411 argv = _free(argv); 00412 return RPMRC_FAIL; 00413 } 00414 00415 { const char *chptr = doUntar(spec, num, quietly); 00416 if (chptr == NULL) 00417 return RPMRC_FAIL; 00418 00419 (void) rpmiobAppend((arg == 'a' ? after : before), chptr, 1); 00420 } 00421 } 00422 00423 if (arg < -1) { 00424 rpmlog(RPMLOG_ERR, _("line %d: Bad %%setup option %s: %s\n"), 00425 spec->lineNum, 00426 poptBadOption(optCon, POPT_BADOPTION_NOALIAS), 00427 poptStrerror(arg)); 00428 before = rpmiobFree(before); 00429 after = rpmiobFree(after); 00430 optCon = poptFreeContext(optCon); 00431 argv = _free(argv); 00432 return RPMRC_FAIL; 00433 } 00434 00435 if (dirName) { 00436 spec->buildSubdir = xstrdup(dirName); 00437 } else { 00438 const char *N, *V; 00439 (void) headerNEVRA(spec->packages->header, &N, NULL, &V, NULL, NULL); 00440 (void) snprintf(buf, sizeof(buf), "%s-%s", N, V); 00441 buf[sizeof(buf)-1] = '\0'; 00442 N = _free(N); 00443 V = _free(V); 00444 spec->buildSubdir = xstrdup(buf); 00445 } 00446 addMacro(spec->macros, "buildsubdir", NULL, spec->buildSubdir, RMIL_SPEC); 00447 00448 optCon = poptFreeContext(optCon); 00449 argv = _free(argv); 00450 00451 /* cd to the build dir */ 00452 { const char * buildDirURL = rpmGenPath(spec->rootURL, "%{_builddir}", ""); 00453 const char *buildDir; 00454 00455 (void) urlPath(buildDirURL, &buildDir); 00456 rc = rpmioMkpath(buildDir, 0755, -1, -1); 00457 sprintf(buf, "cd '%s'", buildDir); 00458 spec->prep = rpmiobAppend(spec->prep, buf, 1); 00459 buildDirURL = _free(buildDirURL); 00460 } 00461 00462 /* delete any old sources */ 00463 if (!leaveDirs) { 00464 sprintf(buf, "rm -rf '%s'", spec->buildSubdir); 00465 spec->prep = rpmiobAppend(spec->prep, buf, 1); 00466 } 00467 00468 /* if necessary, create and cd into the proper dir */ 00469 if (createDir) { 00470 char *mkdir_p; 00471 mkdir_p = rpmExpand("%{?__mkdir_p}%{!?__mkdir_p:mkdir -p}", NULL); 00472 if (!mkdir_p) 00473 mkdir_p = xstrdup("mkdir -p"); 00474 sprintf(buf, "%s '%s'\ncd '%s'", 00475 mkdir_p, spec->buildSubdir, spec->buildSubdir); 00476 mkdir_p = _free(mkdir_p); 00477 spec->prep = rpmiobAppend(spec->prep, buf, 1); 00478 } 00479 00480 /* do the default action */ 00481 if (!createDir && !skipDefaultAction) { 00482 const char *chptr = doUntar(spec, 0, quietly); 00483 if (!chptr) 00484 return RPMRC_FAIL; 00485 spec->prep = rpmiobAppend(spec->prep, chptr, 1); 00486 } 00487 00488 spec->prep = rpmiobAppend(spec->prep, rpmiobStr(before), 0); 00489 before = rpmiobFree(before); 00490 00491 if (!createDir) { 00492 sprintf(buf, "cd '%s'", spec->buildSubdir); 00493 spec->prep = rpmiobAppend(spec->prep, buf, 1); 00494 } 00495 00496 if (createDir && !skipDefaultAction) { 00497 const char * chptr = doUntar(spec, 0, quietly); 00498 if (chptr == NULL) 00499 return RPMRC_FAIL; 00500 spec->prep = rpmiobAppend(spec->prep, chptr, 1); 00501 } 00502 00503 spec->prep = rpmiobAppend(spec->prep, rpmiobStr(after), 0); 00504 after = rpmiobFree(after); 00505 00506 /* XXX FIXME: owner & group fixes were conditioned on !geteuid() */ 00507 /* Fix the owner, group, and permissions of the setup build tree */ 00508 { /*@observer@*/ static const char *fixmacs[] = 00509 { "%{_fixowner}", "%{_fixgroup}", "%{_fixperms}", NULL }; 00510 const char ** fm; 00511 00512 for (fm = fixmacs; *fm; fm++) { 00513 const char *fix; 00514 fix = rpmExpand(*fm, " .", NULL); 00515 if (fix && *fix != '%') 00516 spec->prep = rpmiobAppend(spec->prep, fix, 1); 00517 fix = _free(fix); 00518 } 00519 } 00520 00521 return 0; 00522 } 00523 00524 #ifndef DYING 00525 00531 static rpmRC doPatchMacro(Spec spec, const char * line) 00532 /*@globals rpmGlobalMacroContext, h_errno, 00533 fileSystem, internalState @*/ 00534 /*@modifies spec->prep, rpmGlobalMacroContext, 00535 fileSystem, internalState @*/ 00536 { 00537 char *s; 00538 char *opt_b; 00539 char *opt_d; 00540 rpmuint32_t opt_P, opt_p, opt_R, opt_E, opt_F; 00541 char buf[BUFSIZ], *bp; 00542 rpmuint32_t patch_nums[1024]; /* XXX - we can only handle 1024 patches! */ 00543 int patch_index, x; 00544 00545 memset(patch_nums, 0, sizeof(patch_nums)); 00546 opt_P = opt_p = opt_R = opt_E = 0; 00547 opt_F = rpmExpandNumeric("%{?_default_patch_fuzz}%{!?_default_patch_fuzz:-1}"); 00548 opt_b = NULL; 00549 opt_d = NULL; 00550 patch_index = 0; 00551 00552 if (! strchr(" \t\n", line[6])) { 00553 /* %patchN */ 00554 sprintf(buf, "%%patch -P %s", line + 6); 00555 } else { 00556 strcpy(buf, line); 00557 } 00558 00559 /*@-internalglobs@*/ /* FIX: strtok has state */ 00560 for (bp = buf; (s = strtok(bp, " \t\n")) != NULL;) { 00561 if (bp) { /* remove 1st token (%patch) */ 00562 bp = NULL; 00563 continue; 00564 } 00565 if (!strcmp(s, "-P")) { 00566 opt_P = 1; 00567 } else if (!strcmp(s, "-R")) { 00568 opt_R = 1; 00569 } else if (!strcmp(s, "-E")) { 00570 opt_E = 1; 00571 } else if (!strcmp(s, "-b")) { 00572 /* orig suffix */ 00573 opt_b = strtok(NULL, " \t\n"); 00574 if (! opt_b) { 00575 rpmlog(RPMLOG_ERR, 00576 _("line %d: Need arg to %%patch -b: %s\n"), 00577 spec->lineNum, spec->line); 00578 return RPMRC_FAIL; 00579 } 00580 } else if (!strcmp(s, "-z")) { 00581 /* orig suffix */ 00582 opt_b = strtok(NULL, " \t\n"); 00583 if (! opt_b) { 00584 rpmlog(RPMLOG_ERR, 00585 _("line %d: Need arg to %%patch -z: %s\n"), 00586 spec->lineNum, spec->line); 00587 return RPMRC_FAIL; 00588 } 00589 } else if (!strcmp(s, "-F")) { 00590 /* fuzz factor */ 00591 const char * fnum = (!strchr(" \t\n", s[2]) 00592 ? s+2 : strtok(NULL, " \t\n")); 00593 char * end = NULL; 00594 00595 opt_F = (fnum ? strtol(fnum, &end, 10) : 0); 00596 if (! opt_F || *end) { 00597 rpmlog(RPMLOG_ERR, 00598 _("line %d: Bad arg to %%patch -F: %s\n"), 00599 spec->lineNum, spec->line); 00600 return RPMRC_FAIL; 00601 } 00602 } else if (!strcmp(s, "-d")) { 00603 /* subdirectory */ 00604 opt_d = strtok(NULL, " \t\n"); 00605 if (! opt_d) { 00606 rpmlog(RPMLOG_ERR, 00607 _("line %d: Need arg to %%patch -d: %s\n"), 00608 spec->lineNum, spec->line); 00609 return RPMRC_FAIL; 00610 } 00611 } else if (!strncmp(s, "-p", sizeof("-p")-1)) { 00612 /* unfortunately, we must support -pX */ 00613 if (! strchr(" \t\n", s[2])) { 00614 s = s + 2; 00615 } else { 00616 s = strtok(NULL, " \t\n"); 00617 if (s == NULL) { 00618 rpmlog(RPMLOG_ERR, 00619 _("line %d: Need arg to %%patch -p: %s\n"), 00620 spec->lineNum, spec->line); 00621 return RPMRC_FAIL; 00622 } 00623 } 00624 if (parseNum(s, &opt_p)) { 00625 rpmlog(RPMLOG_ERR, 00626 _("line %d: Bad arg to %%patch -p: %s\n"), 00627 spec->lineNum, spec->line); 00628 return RPMRC_FAIL; 00629 } 00630 } else { 00631 /* Must be a patch num */ 00632 if (patch_index == 1024) { 00633 rpmlog(RPMLOG_ERR, _("Too many patches!\n")); 00634 return RPMRC_FAIL; 00635 } 00636 if (parseNum(s, &(patch_nums[patch_index]))) { 00637 rpmlog(RPMLOG_ERR, _("line %d: Bad arg to %%patch: %s\n"), 00638 spec->lineNum, spec->line); 00639 return RPMRC_FAIL; 00640 } 00641 patch_index++; 00642 } 00643 } 00644 /*@=internalglobs@*/ 00645 00646 /* All args processed */ 00647 00648 if (! opt_P) { 00649 s = doPatch(spec, 0, opt_p, opt_b, opt_R, opt_E, opt_F, opt_d); 00650 if (s == NULL) 00651 return RPMRC_FAIL; 00652 spec->prep = rpmiobAppend(spec->prep, s, 1); 00653 } 00654 00655 for (x = 0; x < patch_index; x++) { 00656 s = doPatch(spec, patch_nums[x], opt_p, opt_b, opt_R, opt_E, opt_F, opt_d); 00657 if (s == NULL) 00658 return RPMRC_FAIL; 00659 spec->prep = rpmiobAppend(spec->prep, s, 1); 00660 } 00661 00662 return RPMRC_OK; 00663 } 00664 #endif 00665 00666 static void prepFetchVerbose(/*@unused@*/ struct Source *sp, 00667 /*@unused@*/ struct stat *st) 00668 /*@globals internalState @*/ 00669 /*@modifies internalState @*/ 00670 { 00671 char *buf; 00672 size_t buf_len; 00673 int xx; 00674 int i; 00675 00676 if (!(rpmIsVerbose() && !quietly && (rpmBTArgs.buildAmount & RPMBUILD_FETCHSOURCE))) 00677 return; 00678 buf_len = 2*80; 00679 if ((buf = (char *)malloc(buf_len)) == NULL) 00680 return; 00681 xx = snprintf(buf, buf_len, "%s%d:", (sp->flags & RPMFILE_SOURCE) ? "Source" : "Patch", sp->num); 00682 for (i = (int)strlen(buf); i <= 11; i++) 00683 buf[i] = ' '; 00684 xx = snprintf(buf+i, buf_len-i, "%-52.52s", sp->source); 00685 i = (int)strlen(buf); 00686 if (st != NULL) 00687 xx = snprintf(buf+i, buf_len-i, " %9lu Bytes\n", (unsigned long)st->st_size); 00688 else 00689 xx = snprintf(buf+i, buf_len-i, " ...MISSING\n"); 00690 rpmlog(RPMLOG_NOTICE, "%s", buf); 00691 buf = _free(buf); 00692 return; 00693 } 00694 00698 static int prepFetch(Spec spec) 00699 /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/ 00700 /*@modifies rpmGlobalMacroContext, fileSystem, internalState @*/ 00701 { 00702 #if defined(RPM_VENDOR_OPENPKG) /* splitted-source-directory */ 00703 const char *Smacro; 00704 #endif 00705 const char *Lmacro, *Lurlfn = NULL; 00706 const char *Rmacro, *Rurlfn = NULL; 00707 struct Source *sp; 00708 struct stat st; 00709 rpmRC rpmrc; 00710 int ec, rc; 00711 char *cp; 00712 00713 /* XXX insure that %{_sourcedir} exists */ 00714 rpmrc = RPMRC_OK; 00715 Lurlfn = rpmGenPath(NULL, "%{?_sourcedir}", NULL); 00716 if (Lurlfn != NULL && *Lurlfn != '\0') 00717 rpmrc = rpmMkdirPath(Lurlfn, "_sourcedir"); 00718 Lurlfn = _free(Lurlfn); 00719 if (rpmrc != RPMRC_OK) 00720 return -1; 00721 00722 /* XXX insure that %{_patchdir} exists */ 00723 rpmrc = RPMRC_OK; 00724 Lurlfn = rpmGenPath(NULL, "%{?_patchdir}", NULL); 00725 if (Lurlfn != NULL && *Lurlfn != '\0') 00726 rpmrc = rpmMkdirPath(Lurlfn, "_patchdir"); 00727 Lurlfn = _free(Lurlfn); 00728 if (rpmrc != RPMRC_OK) 00729 return -1; 00730 00731 /* XXX insure that %{_icondir} exists */ 00732 rpmrc = RPMRC_OK; 00733 Lurlfn = rpmGenPath(NULL, "%{?_icondir}", NULL); 00734 if (Lurlfn != NULL && *Lurlfn != '\0') 00735 rpmrc = rpmMkdirPath(Lurlfn, "_icondir"); 00736 Lurlfn = _free(Lurlfn); 00737 if (rpmrc != RPMRC_OK) 00738 return -1; 00739 00740 if (rpmIsVerbose() && !quietly && (rpmBTArgs.buildAmount & RPMBUILD_FETCHSOURCE)) 00741 rpmlog(RPMLOG_NOTICE, "Checking source and patch file(s):\n"); 00742 00743 ec = 0; 00744 for (sp = spec->sources; sp != NULL; sp = sp->next) { 00745 00746 #if defined(RPM_VENDOR_OPENPKG) /* splitted-source-directory */ 00747 Smacro = "%{?_specdir}/"; 00748 #endif 00749 #if defined(RPM_VENDOR_OPENPKG) /* splitted-source-directory */ 00750 if (! (Lmacro = getSourceDir(sp->flags, sp->source))) 00751 #else 00752 if (! (Lmacro = getSourceDir(sp->flags))) 00753 #endif 00754 continue; 00755 if (sp->flags & RPMFILE_SOURCE) { 00756 Rmacro = "%{?_Rsourcedir}/"; 00757 } else 00758 if (sp->flags & RPMFILE_PATCH) { 00759 Rmacro = "%{?_Rpatchdir}/"; 00760 } else 00761 if (sp->flags & RPMFILE_ICON) { 00762 Rmacro = "%{?_Ricondir}/"; 00763 } else 00764 continue; 00765 00766 #if defined(RPM_VENDOR_OPENPKG) /* splitted-source-directory */ 00767 /* support splitted source directories, i.e., source files which 00768 are alternatively placed into the .spec directory and picked 00769 up from there, too. */ 00770 Lurlfn = rpmGenPath(NULL, Smacro, sp->source); 00771 rc = Lstat(Lurlfn, &st); 00772 if (rc == 0) { 00773 prepFetchVerbose(sp, &st); 00774 goto bottom; 00775 } 00776 #endif 00777 Lurlfn = rpmGenPath(NULL, Lmacro, sp->source); 00778 rc = Lstat(Lurlfn, &st); 00779 if (rc == 0) { 00780 /*@-noeffect@*/ 00781 prepFetchVerbose(sp, &st); 00782 /*@=noeffect@*/ 00783 goto bottom; 00784 } 00785 /*@-noeffect@*/ 00786 prepFetchVerbose(sp, NULL); 00787 /*@=noeffect@*/ 00788 if (errno != ENOENT) { 00789 ec++; 00790 rpmlog(RPMLOG_ERR, _("Missing %s%d %s: %s\n"), 00791 ((sp->flags & RPMFILE_SOURCE) ? "Source" : "Patch"), 00792 sp->num, sp->source, strerror(ENOENT)); 00793 goto bottom; 00794 } 00795 00796 /* try to fetch via macro-controlled remote locations */ 00797 cp = rpmExpand(Rmacro, NULL); 00798 if (cp != NULL && strcmp(cp, "/") != 0) { 00799 cp = _free(cp); 00800 Rurlfn = rpmGenPath(NULL, Rmacro, sp->source); 00801 if (!(Rurlfn == NULL || Rurlfn[0] == '\0' || !strcmp(Rurlfn, "/") || !strcmp(Lurlfn, Rurlfn))) { 00802 rpmlog(RPMLOG_NOTICE, _("Fetching(%s%d): %s\n"), 00803 (sp->flags & RPMFILE_SOURCE) ? "Source" : "Patch", sp->num, Rurlfn); 00804 rc = urlGetFile(Rurlfn, Lurlfn); 00805 if (rc == 0) 00806 goto bottom; 00807 else { 00808 rpmlog(RPMLOG_ERR, _("Fetching %s%d failed: %s\n"), 00809 (sp->flags & RPMFILE_SOURCE) ? "Source" : "Patch", sp->num, ftpStrerror(rc)); 00810 ec++; 00811 } 00812 } 00813 } 00814 cp = _free(cp); 00815 00816 /* try to fetch from original location */ 00817 rpmlog(RPMLOG_NOTICE, _("Fetching(%s%d): %s\n"), 00818 (sp->flags & RPMFILE_SOURCE) ? "Source" : "Patch", sp->num, sp->fullSource); 00819 rc = urlGetFile(sp->fullSource, Lurlfn); 00820 if (rc == 0) 00821 goto bottom; 00822 else { 00823 rpmlog(RPMLOG_ERR, _("Fetching %s%d failed: %s\n"), 00824 (sp->flags & RPMFILE_SOURCE) ? "Source" : "Patch", sp->num, ftpStrerror(rc)); 00825 ec++; 00826 } 00827 00828 rpmlog(RPMLOG_ERR, _("Missing %s%d: %s: %s\n"), 00829 ((sp->flags & RPMFILE_SOURCE) ? "Source" : "Patch"), 00830 sp->num, sp->source, strerror(ENOENT)); 00831 ec++; 00832 00833 bottom: 00834 Lurlfn = _free(Lurlfn); 00835 Rurlfn = _free(Rurlfn); 00836 } 00837 00838 return ec; 00839 } 00840 00841 int parsePrep(Spec spec, int verify) 00842 { 00843 rpmParseState nextPart; 00844 int res, rc; 00845 rpmiob iob; 00846 ARGV_t saveLines = NULL; 00847 ARGV_t lines; 00848 const char * cp; 00849 int xx; 00850 00851 if (spec->prep != NULL) { 00852 rpmlog(RPMLOG_ERR, _("line %d: second %%prep\n"), spec->lineNum); 00853 return RPMRC_FAIL; 00854 } 00855 00856 spec->prep = rpmiobNew(0); 00857 00858 /* There are no options to %prep */ 00859 if ((rc = readLine(spec, STRIP_NOTHING)) > 0) 00860 return PART_NONE; 00861 if (rc) 00862 return rc; 00863 00864 /* Check to make sure that all sources/patches are present. */ 00865 if (verify) { 00866 rc = prepFetch(spec); 00867 if (rc) 00868 return RPMRC_FAIL; 00869 } 00870 00871 iob = rpmiobNew(0); 00872 00873 while ((nextPart = isPart(spec)) == PART_NONE) { 00874 /* Need to expand the macros inline. That way we */ 00875 /* can give good line number information on error. */ 00876 iob = rpmiobAppend(iob, spec->line, 0); 00877 if ((rc = readLine(spec, STRIP_NOTHING)) > 0) { 00878 nextPart = PART_NONE; 00879 break; 00880 } 00881 if (rc) 00882 return rc; 00883 } 00884 00885 xx = argvSplit(&saveLines, rpmiobStr(iob), "\n"); 00886 00887 /*@-usereleased@*/ 00888 for (lines = saveLines; *lines; lines++) { 00889 res = 0; 00890 for (cp = *lines; *cp == ' ' || *cp == '\t'; cp++) 00891 {}; 00892 if (!strncmp(cp, "%setup", sizeof("%setup")-1)) { 00893 res = doSetupMacro(spec, cp); 00894 #ifndef DYING 00895 } else if (! strncmp(cp, "%patch", sizeof("%patch")-1)) { 00896 res = doPatchMacro(spec, cp); 00897 #endif 00898 } else { 00899 spec->prep = rpmiobAppend(spec->prep, *lines, 1); 00900 } 00901 if (res && !spec->force) { 00902 saveLines = argvFree(saveLines); 00903 iob = rpmiobFree(iob); 00904 return res; 00905 } 00906 } 00907 /*@=usereleased@*/ 00908 00909 saveLines = argvFree(saveLines); 00910 iob = rpmiobFree(iob); 00911 00912 return nextPart; 00913 }