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

- File List
- Globals

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