- Main Page
- Related Pages
- Modules
- Data Structures
- Files

# build/parsePrep.c

Go to the documentation of this file.

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