build/parseSpec.c

Go to the documentation of this file.
00001 
00006 #include "system.h"
00007 
00008 #include <rpmio_internal.h>
00009 #include <rpmbuild.h>
00010 #include "rpmds.h"
00011 #include "rpmts.h"
00012 #include "debug.h"
00013 
00014 /*@access FD_t @*/      /* compared with NULL */
00015 
00018 /*@unchecked@*/
00019 static struct PartRec {
00020     int part;
00021     int len;
00022 /*@observer@*/ /*@null@*/
00023     const char * token;
00024 } partList[] = {
00025     { PART_PREAMBLE,      0, "%package"},
00026     { PART_PREP,          0, "%prep"},
00027     { PART_BUILD,         0, "%build"},
00028     { PART_INSTALL,       0, "%install"},
00029     { PART_CHECK,         0, "%check"},
00030     { PART_CLEAN,         0, "%clean"},
00031     { PART_PREUN,         0, "%preun"},
00032     { PART_POSTUN,        0, "%postun"},
00033     { PART_PRETRANS,      0, "%pretrans"},
00034     { PART_POSTTRANS,     0, "%posttrans"},
00035     { PART_PRE,           0, "%pre"},
00036     { PART_POST,          0, "%post"},
00037     { PART_FILES,         0, "%files"},
00038     { PART_CHANGELOG,     0, "%changelog"},
00039     { PART_DESCRIPTION,   0, "%description"},
00040     { PART_TRIGGERPOSTUN, 0, "%triggerpostun"},
00041     { PART_TRIGGERPREIN,  0, "%triggerprein"},
00042     { PART_TRIGGERUN,     0, "%triggerun"},
00043     { PART_TRIGGERIN,     0, "%triggerin"},
00044     { PART_TRIGGERIN,     0, "%trigger"},
00045     { PART_VERIFYSCRIPT,  0, "%verifyscript"},
00046     {0, 0, 0}
00047 };
00048 
00051 static inline void initParts(struct PartRec *p)
00052         /*@modifies p->len @*/
00053 {
00054     for (; p->token != NULL; p++)
00055         p->len = strlen(p->token);
00056 }
00057 
00058 rpmParseState isPart(const char *line)
00059 {
00060     struct PartRec *p;
00061 
00062 /*@-boundsread@*/
00063     if (partList[0].len == 0)
00064         initParts(partList);
00065 /*@=boundsread@*/
00066     
00067     for (p = partList; p->token != NULL; p++) {
00068         char c;
00069         if (xstrncasecmp(line, p->token, p->len))
00070             continue;
00071 /*@-boundsread@*/
00072         c = *(line + p->len);
00073 /*@=boundsread@*/
00074         if (c == '\0' || xisspace(c))
00075             break;
00076     }
00077 
00078     return (p->token ? p->part : PART_NONE);
00079 }
00080 
00083 static int matchTok(const char *token, const char *line)
00084         /*@*/
00085 {
00086     const char *b, *be = line;
00087     size_t toklen = strlen(token);
00088     int rc = 0;
00089 
00090 /*@-boundsread@*/
00091     while ( *(b = be) != '\0' ) {
00092         SKIPSPACE(b);
00093         be = b;
00094         SKIPNONSPACE(be);
00095         if (be == b)
00096             break;
00097         if (toklen != (be-b) || xstrncasecmp(token, b, (be-b)))
00098             continue;
00099         rc = 1;
00100         break;
00101     }
00102 /*@=boundsread@*/
00103 
00104     return rc;
00105 }
00106 
00107 /*@-boundswrite@*/
00108 void handleComments(char *s)
00109 {
00110     SKIPSPACE(s);
00111     if (*s == '#')
00112         *s = '\0';
00113 }
00114 /*@=boundswrite@*/
00115 
00118 static void forceIncludeFile(Spec spec, const char * fileName)
00119         /*@modifies spec->fileStack @*/
00120 {
00121     OFI_t * ofi;
00122 
00123     ofi = newOpenFileInfo();
00124     ofi->fileName = xstrdup(fileName);
00125     ofi->next = spec->fileStack;
00126     spec->fileStack = ofi;
00127 }
00128 
00131 /*@-boundswrite@*/
00132 static int copyNextLineFromOFI(Spec spec, OFI_t *ofi)
00133 {
00134     char ch;
00135 
00136     /* Expand next line from file into line buffer */
00137     if (!(spec->nextline && *spec->nextline)) {
00138         int pc = 0, bc = 0, nc = 0;
00139         char *from, *to, *p;
00140         to = spec->lbufPtr ? spec->lbufPtr : spec->lbuf;
00141         from = ofi->readPtr;
00142         ch = ' ';
00143         while (*from && ch != '\n')
00144             ch = *to++ = *from++;
00145 /*@-mods@*/
00146         spec->lbufPtr = to;
00147 /*@=mods@*/
00148         *to++ = '\0';
00149         ofi->readPtr = from;
00150 
00151         /* Check if we need another line before expanding the buffer. */
00152         for (p = spec->lbuf; *p; p++) {
00153             switch (*p) {
00154                 case '\\':
00155                     switch (*(p+1)) {
00156                         case '\n': p++, nc = 1; /*@innerbreak@*/ break;
00157                         case '\0': /*@innerbreak@*/ break;
00158                         default: p++; /*@innerbreak@*/ break;
00159                     }
00160                     /*@switchbreak@*/ break;
00161                 case '\n': nc = 0; /*@switchbreak@*/ break;
00162                 case '%':
00163                     switch (*(p+1)) {
00164                         case '{': p++, bc++; /*@innerbreak@*/ break;
00165                         case '(': p++, pc++; /*@innerbreak@*/ break;
00166                         case '%': p++; /*@innerbreak@*/ break;
00167                     }
00168                     /*@switchbreak@*/ break;
00169                 case '{': if (bc > 0) bc++; /*@switchbreak@*/ break;
00170                 case '}': if (bc > 0) bc--; /*@switchbreak@*/ break;
00171                 case '(': if (pc > 0) pc++; /*@switchbreak@*/ break;
00172                 case ')': if (pc > 0) pc--; /*@switchbreak@*/ break;
00173             }
00174         }
00175         
00176         /* If it doesn't, ask for one more line. We need a better
00177          * error code for this. */
00178         if (pc || bc || nc ) {
00179 /*@-observertrans -readonlytrans@*/
00180             spec->nextline = "";
00181 /*@=observertrans =readonlytrans@*/
00182             return RPMERR_UNMATCHEDIF;
00183         }
00184 /*@-mods@*/
00185         spec->lbufPtr = spec->lbuf;
00186 /*@=mods@*/
00187 
00188         /* Don't expand macros (eg. %define) in false branch of %if clause */
00189         if (spec->readStack->reading &&
00190             expandMacros(spec, spec->macros, spec->lbuf, sizeof(spec->lbuf))) {
00191                 rpmError(RPMERR_BADSPEC, _("line %d: %s\n"),
00192                         spec->lineNum, spec->lbuf);
00193                 return RPMERR_BADSPEC;
00194         }
00195         spec->nextline = spec->lbuf;
00196     }
00197 
00198     return 0;
00199 }
00200 
00203 static void copyNextLineFinish(Spec spec, int strip)
00204 {
00205     char *last;
00206     char ch;
00207 
00208     /* Find next line in expanded line buffer */
00209     spec->line = last = spec->nextline;
00210     ch = ' ';
00211     while (*spec->nextline && ch != '\n') {
00212         ch = *spec->nextline++;
00213         if (!xisspace(ch))
00214             last = spec->nextline;
00215     }
00216 
00217     /* Save 1st char of next line in order to terminate current line. */
00218     if (*spec->nextline != '\0') {
00219         spec->nextpeekc = *spec->nextline;
00220         *spec->nextline = '\0';
00221     }
00222     
00223     if (strip & STRIP_COMMENTS)
00224         handleComments(spec->line);
00225     
00226     if (strip & STRIP_TRAILINGSPACE)
00227         *last = '\0';
00228 }
00229 /*@=boundswrite@*/
00230 
00231 static int readLineFromOFI(Spec spec, OFI_t *ofi)
00232 {
00233 
00234 retry:
00235     /* Make sure the current file is open */
00236     /*@-branchstate@*/
00237     if (ofi->fd == NULL) {
00238         ofi->fd = Fopen(ofi->fileName, "r.fpio");
00239         if (ofi->fd == NULL || Ferror(ofi->fd)) {
00240             /* XXX Fstrerror */
00241             rpmError(RPMERR_BADSPEC, _("Unable to open %s: %s\n"),
00242                      ofi->fileName, Fstrerror(ofi->fd));
00243             return RPMERR_BADSPEC;
00244         }
00245         spec->lineNum = ofi->lineNum = 0;
00246     }
00247 
00248     /*@=branchstate@*/
00249     if (!(ofi->readPtr && *(ofi->readPtr))) {
00250         /*@-type@*/ /* FIX: cast? */
00251         FILE * f = fdGetFp(ofi->fd);
00252         /*@=type@*/
00253         if (f == NULL || !fgets(ofi->readBuf, BUFSIZ, f)) {
00254             /* EOF */
00255             if (spec->readStack->next) {
00256                 rpmError(RPMERR_UNMATCHEDIF, _("Unclosed %%if\n"));
00257                 return RPMERR_UNMATCHEDIF;
00258             }
00259 
00260             /* remove this file from the stack */
00261             spec->fileStack = ofi->next;
00262             (void) Fclose(ofi->fd);
00263             ofi->fileName = _free(ofi->fileName);
00264             ofi = _free(ofi);
00265 
00266             /* only on last file do we signal EOF to caller */
00267             ofi = spec->fileStack;
00268             if (ofi == NULL)
00269                 return 1;
00270 
00271             /* otherwise, go back and try the read again. */
00272             goto retry;
00273         }
00274         ofi->readPtr = ofi->readBuf;
00275         ofi->lineNum++;
00276         spec->lineNum = ofi->lineNum;
00277         if (spec->sl) {
00278             speclines sl = spec->sl;
00279             if (sl->sl_nlines == sl->sl_nalloc) {
00280                 sl->sl_nalloc += 100;
00281                 sl->sl_lines = (char **) xrealloc(sl->sl_lines, 
00282                         sl->sl_nalloc * sizeof(*(sl->sl_lines)));
00283             }
00284             sl->sl_lines[sl->sl_nlines++] = xstrdup(ofi->readBuf);
00285         }
00286     }
00287     return 0;
00288 }
00289 
00290 /*@-boundswrite@*/
00291 int readLine(Spec spec, int strip)
00292 {
00293 #ifdef  DYING
00294     const char *arch;
00295     const char *os;
00296 #endif
00297     char  *s;
00298     int match;
00299     struct ReadLevelEntry *rl;
00300     OFI_t *ofi = spec->fileStack;
00301     int rc;
00302     
00303 #ifdef  DYING
00304     arch = NULL;
00305     rpmGetArchInfo(&arch, NULL);
00306     os = NULL;
00307     rpmGetOsInfo(&os, NULL);
00308 #endif
00309 
00310     /* Restore 1st char in (possible) next line */
00311     if (spec->nextline != NULL && spec->nextpeekc != '\0') {
00312         *spec->nextline = spec->nextpeekc;
00313         spec->nextpeekc = '\0';
00314     } else {
00315     retry:
00316       /* Make sure we have something in the read buffer */
00317       if ((rc = readLineFromOFI(spec, ofi)) != 0) {
00318           return rc;
00319       }
00320 
00321       if ((rc = copyNextLineFromOFI(spec, ofi)) != 0) {
00322         if (rc == RPMERR_UNMATCHEDIF)
00323             goto retry;
00324         return rc;
00325       }
00326     }
00327 
00328     /* Copy next file line into the spec line buffer */
00329     copyNextLineFinish(spec, strip);
00330 
00331     s = spec->line;
00332     SKIPSPACE(s);
00333 
00334     match = -1;
00335     if (!spec->readStack->reading && !strncmp("%if", s, sizeof("%if")-1)) {
00336         match = 0;
00337     } else if (! strncmp("%ifarch", s, sizeof("%ifarch")-1)) {
00338         const char *arch = rpmExpand("%{_target_cpu}", NULL);
00339         s += 7;
00340         match = matchTok(arch, s);
00341         arch = _free(arch);
00342     } else if (! strncmp("%ifnarch", s, sizeof("%ifnarch")-1)) {
00343         const char *arch = rpmExpand("%{_target_cpu}", NULL);
00344         s += 8;
00345         match = !matchTok(arch, s);
00346         arch = _free(arch);
00347     } else if (! strncmp("%ifos", s, sizeof("%ifos")-1)) {
00348         const char *os = rpmExpand("%{_target_os}", NULL);
00349         s += 5;
00350         match = matchTok(os, s);
00351         os = _free(os);
00352     } else if (! strncmp("%ifnos", s, sizeof("%ifnos")-1)) {
00353         const char *os = rpmExpand("%{_target_os}", NULL);
00354         s += 6;
00355         match = !matchTok(os, s);
00356         os = _free(os);
00357     } else if (! strncmp("%if", s, sizeof("%if")-1)) {
00358         s += 3;
00359         match = parseExpressionBoolean(spec, s);
00360         if (match < 0) {
00361             rpmError(RPMERR_UNMATCHEDIF,
00362                         _("%s:%d: parseExpressionBoolean returns %d\n"),
00363                         ofi->fileName, ofi->lineNum, match);
00364             return RPMERR_BADSPEC;
00365         }
00366     } else if (! strncmp("%else", s, sizeof("%else")-1)) {
00367         s += 5;
00368         if (! spec->readStack->next) {
00369             /* Got an else with no %if ! */
00370             rpmError(RPMERR_UNMATCHEDIF,
00371                         _("%s:%d: Got a %%else with no %%if\n"),
00372                         ofi->fileName, ofi->lineNum);
00373             return RPMERR_UNMATCHEDIF;
00374         }
00375         spec->readStack->reading =
00376             spec->readStack->next->reading && ! spec->readStack->reading;
00377         spec->line[0] = '\0';
00378     } else if (! strncmp("%endif", s, sizeof("%endif")-1)) {
00379         s += 6;
00380         if (! spec->readStack->next) {
00381             /* Got an end with no %if ! */
00382             rpmError(RPMERR_UNMATCHEDIF,
00383                         _("%s:%d: Got a %%endif with no %%if\n"),
00384                         ofi->fileName, ofi->lineNum);
00385             return RPMERR_UNMATCHEDIF;
00386         }
00387         rl = spec->readStack;
00388         spec->readStack = spec->readStack->next;
00389         free(rl);
00390         spec->line[0] = '\0';
00391     } else if (! strncmp("%include", s, sizeof("%include")-1)) {
00392         char *fileName, *endFileName, *p;
00393 
00394         s += 8;
00395         fileName = s;
00396         if (! xisspace(*fileName)) {
00397             rpmError(RPMERR_BADSPEC, _("malformed %%include statement\n"));
00398             return RPMERR_BADSPEC;
00399         }
00400         SKIPSPACE(fileName);
00401         endFileName = fileName;
00402         SKIPNONSPACE(endFileName);
00403         p = endFileName;
00404         SKIPSPACE(p);
00405         if (*p != '\0') {
00406             rpmError(RPMERR_BADSPEC, _("malformed %%include statement\n"));
00407             return RPMERR_BADSPEC;
00408         }
00409         *endFileName = '\0';
00410 
00411         forceIncludeFile(spec, fileName);
00412 
00413         ofi = spec->fileStack;
00414         goto retry;
00415     }
00416 
00417     if (match != -1) {
00418         rl = xmalloc(sizeof(*rl));
00419         rl->reading = spec->readStack->reading && match;
00420         rl->next = spec->readStack;
00421         spec->readStack = rl;
00422         spec->line[0] = '\0';
00423     }
00424 
00425     if (! spec->readStack->reading) {
00426         spec->line[0] = '\0';
00427     }
00428 
00429     /*@-compmempass@*/ /* FIX: spec->readStack->next should be dependent */
00430     return 0;
00431     /*@=compmempass@*/
00432 }
00433 /*@=boundswrite@*/
00434 
00435 void closeSpec(Spec spec)
00436 {
00437     OFI_t *ofi;
00438 
00439     while (spec->fileStack) {
00440         ofi = spec->fileStack;
00441         spec->fileStack = spec->fileStack->next;
00442         if (ofi->fd) (void) Fclose(ofi->fd);
00443         ofi->fileName = _free(ofi->fileName);
00444         ofi = _free(ofi);
00445     }
00446 }
00447 
00448 /*@-redecl@*/
00449 /*@unchecked@*/
00450 extern int noLang;              /* XXX FIXME: pass as arg */
00451 /*@=redecl@*/
00452 
00453 /*@todo Skip parse recursion if os is not compatible. @*/
00454 /*@-boundswrite@*/
00455 int parseSpec(rpmts ts, const char *specFile, const char *rootURL,
00456                 const char *buildRootURL, int recursing, const char *passPhrase,
00457                 char *cookie, int anyarch, int force)
00458 {
00459     rpmParseState parsePart = PART_PREAMBLE;
00460     int initialPackage = 1;
00461 #ifdef  DYING
00462     const char *saveArch;
00463 #endif
00464     Package pkg;
00465     Spec spec;
00466     
00467     /* Set up a new Spec structure with no packages. */
00468     spec = newSpec();
00469 
00470     /*
00471      * Note: rpmGetPath should guarantee a "canonical" path. That means
00472      * that the following pathologies should be weeded out:
00473      *          //bin//sh
00474      *          //usr//bin/
00475      *          /.././../usr/../bin//./sh (XXX FIXME: dots not handled yet)
00476      */
00477     spec->specFile = rpmGetPath(specFile, NULL);
00478     spec->fileStack = newOpenFileInfo();
00479     spec->fileStack->fileName = xstrdup(spec->specFile);
00480     if (buildRootURL) {
00481         const char * buildRoot;
00482         (void) urlPath(buildRootURL, &buildRoot);
00483         /*@-branchstate@*/
00484         if (*buildRoot == '\0') buildRoot = "/";
00485         /*@=branchstate@*/
00486         if (!strcmp(buildRoot, "/")) {
00487             rpmError(RPMERR_BADSPEC,
00488                      _("BuildRoot can not be \"/\": %s\n"), buildRootURL);
00489             return RPMERR_BADSPEC;
00490         }
00491         spec->gotBuildRootURL = 1;
00492         spec->buildRootURL = xstrdup(buildRootURL);
00493         addMacro(spec->macros, "buildroot", NULL, buildRoot, RMIL_SPEC);
00494     }
00495     addMacro(NULL, "_docdir", NULL, "%{_defaultdocdir}", RMIL_SPEC);
00496     spec->recursing = recursing;
00497     spec->anyarch = anyarch;
00498     spec->force = force;
00499 
00500     if (rootURL)
00501         spec->rootURL = xstrdup(rootURL);
00502     if (passPhrase)
00503         spec->passPhrase = xstrdup(passPhrase);
00504     if (cookie)
00505         spec->cookie = xstrdup(cookie);
00506 
00507     spec->timeCheck = rpmExpandNumeric("%{_timecheck}");
00508 
00509     /* All the parse*() functions expect to have a line pre-read */
00510     /* in the spec's line buffer.  Except for parsePreamble(),   */
00511     /* which handles the initial entry into a spec file.         */
00512     
00513     /*@-infloops@*/     /* LCL: parsePart is modified @*/
00514     while (parsePart < PART_LAST && parsePart != PART_NONE) {
00515         switch (parsePart) {
00516         case PART_PREAMBLE:
00517             parsePart = parsePreamble(spec, initialPackage);
00518             initialPackage = 0;
00519             /*@switchbreak@*/ break;
00520         case PART_PREP:
00521             parsePart = parsePrep(spec);
00522             /*@switchbreak@*/ break;
00523         case PART_BUILD:
00524         case PART_INSTALL:
00525         case PART_CHECK:
00526         case PART_CLEAN:
00527             parsePart = parseBuildInstallClean(spec, parsePart);
00528             /*@switchbreak@*/ break;
00529         case PART_CHANGELOG:
00530             parsePart = parseChangelog(spec);
00531             /*@switchbreak@*/ break;
00532         case PART_DESCRIPTION:
00533             parsePart = parseDescription(spec);
00534             /*@switchbreak@*/ break;
00535 
00536         case PART_PRE:
00537         case PART_POST:
00538         case PART_PREUN:
00539         case PART_POSTUN:
00540         case PART_PRETRANS:
00541         case PART_POSTTRANS:
00542         case PART_VERIFYSCRIPT:
00543         case PART_TRIGGERPREIN:
00544         case PART_TRIGGERIN:
00545         case PART_TRIGGERUN:
00546         case PART_TRIGGERPOSTUN:
00547             parsePart = parseScript(spec, parsePart);
00548             /*@switchbreak@*/ break;
00549 
00550         case PART_FILES:
00551             parsePart = parseFiles(spec);
00552             /*@switchbreak@*/ break;
00553 
00554         case PART_NONE:         /* XXX avoid gcc whining */
00555         case PART_LAST:
00556         case PART_BUILDARCHITECTURES:
00557             /*@switchbreak@*/ break;
00558         }
00559 
00560         if (parsePart >= PART_LAST) {
00561             spec = freeSpec(spec);
00562             return parsePart;
00563         }
00564 
00565         if (parsePart == PART_BUILDARCHITECTURES) {
00566             int index;
00567             int x;
00568 
00569             closeSpec(spec);
00570 
00571             /* LCL: sizeof(spec->BASpecs[0]) -nullderef whine here */
00572             spec->BASpecs = xcalloc(spec->BACount, sizeof(*spec->BASpecs));
00573             index = 0;
00574             if (spec->BANames != NULL)
00575             for (x = 0; x < spec->BACount; x++) {
00576 
00577                 /* Skip if not arch is not compatible. */
00578                 if (!rpmMachineScore(RPM_MACHTABLE_BUILDARCH, spec->BANames[x]))
00579                     /*@innercontinue@*/ continue;
00580 #ifdef  DYING
00581                 rpmGetMachine(&saveArch, NULL);
00582                 saveArch = xstrdup(saveArch);
00583                 rpmSetMachine(spec->BANames[x], NULL);
00584 #else
00585                 addMacro(NULL, "_target_cpu", NULL, spec->BANames[x], RMIL_RPMRC);
00586 #endif
00587                 spec->BASpecs[index] = NULL;
00588                 if (parseSpec(ts, specFile, spec->rootURL, buildRootURL, 1,
00589                                   passPhrase, cookie, anyarch, force)
00590                  || (spec->BASpecs[index] = rpmtsSetSpec(ts, NULL)) == NULL)
00591                 {
00592                         spec->BACount = index;
00593 /*@-nullstate@*/
00594                         spec = freeSpec(spec);
00595                         return RPMERR_BADSPEC;
00596 /*@=nullstate@*/
00597                 }
00598 #ifdef  DYING
00599                 rpmSetMachine(saveArch, NULL);
00600                 saveArch = _free(saveArch);
00601 #else
00602                 delMacro(NULL, "_target_cpu");
00603 #endif
00604                 index++;
00605             }
00606 
00607             spec->BACount = index;
00608             if (! index) {
00609                 rpmError(RPMERR_BADSPEC,
00610                         _("No compatible architectures found for build\n"));
00611 /*@-nullstate@*/
00612                 spec = freeSpec(spec);
00613                 return RPMERR_BADSPEC;
00614 /*@=nullstate@*/
00615             }
00616 
00617             /*
00618              * Return the 1st child's fully parsed Spec structure.
00619              * The restart of the parse when encountering BuildArch
00620              * causes problems for "rpm -q --specfile". This is
00621              * still a hack because there may be more than 1 arch
00622              * specified (unlikely but possible.) There's also the
00623              * further problem that the macro context, particularly
00624              * %{_target_cpu}, disagrees with the info in the header.
00625              */
00626             /*@-branchstate@*/
00627             if (spec->BACount >= 1) {
00628                 Spec nspec = spec->BASpecs[0];
00629                 spec->BASpecs = _free(spec->BASpecs);
00630                 spec = freeSpec(spec);
00631                 spec = nspec;
00632             }
00633             /*@=branchstate@*/
00634 
00635             (void) rpmtsSetSpec(ts, spec);
00636             return 0;
00637         }
00638     }
00639     /*@=infloops@*/     /* LCL: parsePart is modified @*/
00640 
00641     /* Check for description in each package and add arch and os */
00642   {
00643 #ifdef  DYING
00644     const char *arch = NULL;
00645     const char *os = NULL;
00646     char *myos = NULL;
00647 
00648     rpmGetArchInfo(&arch, NULL);
00649     rpmGetOsInfo(&os, NULL);
00650     /*
00651      * XXX Capitalizing the 'L' is needed to insure that old
00652      * XXX os-from-uname (e.g. "Linux") is compatible with the new
00653      * XXX os-from-platform (e.g "linux" from "sparc-*-linux").
00654      * XXX A copy of this string is embedded in headers.
00655      */
00656     if (!strcmp(os, "linux")) {
00657         myos = xstrdup(os);
00658         *myos = 'L';
00659         os = myos;
00660     }
00661 #else
00662     const char *platform = rpmExpand("%{_target_platform}", NULL);
00663     const char *arch = rpmExpand("%{_target_cpu}", NULL);
00664     const char *os = rpmExpand("%{_target_os}", NULL);
00665 #endif
00666 
00667     for (pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
00668         if (!headerIsEntry(pkg->header, RPMTAG_DESCRIPTION)) {
00669             const char * name;
00670             (void) headerNVR(pkg->header, &name, NULL, NULL);
00671             rpmError(RPMERR_BADSPEC, _("Package has no %%description: %s\n"),
00672                         name);
00673             spec = freeSpec(spec);
00674             return RPMERR_BADSPEC;
00675         }
00676 
00677         (void) headerAddEntry(pkg->header, RPMTAG_OS, RPM_STRING_TYPE, os, 1);
00678         (void) headerAddEntry(pkg->header, RPMTAG_ARCH,
00679                 RPM_STRING_TYPE, arch, 1);
00680         if (!headerIsEntry(pkg->header, RPMTAG_RHNPLATFORM))
00681             (void) headerAddEntry(pkg->header, RPMTAG_RHNPLATFORM,
00682                 RPM_STRING_TYPE, arch, 1);
00683         (void) headerAddEntry(pkg->header, RPMTAG_PLATFORM,
00684                 RPM_STRING_TYPE, platform, 1);
00685 
00686         pkg->ds = rpmdsThis(pkg->header, RPMTAG_REQUIRENAME, RPMSENSE_EQUAL);
00687 
00688     }
00689 
00690 #ifdef  DYING
00691     myos = _free(myos);
00692 #else
00693     platform = _free(platform);
00694     arch = _free(arch);
00695     os = _free(os);
00696 #endif
00697   }
00698 
00699     closeSpec(spec);
00700     (void) rpmtsSetSpec(ts, spec);
00701 
00702     return 0;
00703 }
00704 /*@=boundswrite@*/

Generated on Wed Jan 21 20:52:56 2009 for rpm by  doxygen 1.4.7