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