rpm
4.5
|
00001 00006 #include "system.h" 00007 00008 #include "buildio.h" 00009 #include "rpmds.h" 00010 #include "rpmfi.h" 00011 #include "rpmts.h" 00012 00013 #include "debug.h" 00014 00015 /*@-redecl@*/ 00016 extern int specedit; 00017 /*@=redecl@*/ 00018 00019 #define SKIPWHITE(_x) {while(*(_x) && (xisspace(*_x) || *(_x) == ',')) (_x)++;} 00020 #define SKIPNONWHITE(_x){while(*(_x) &&!(xisspace(*_x) || *(_x) == ',')) (_x)++;} 00021 00022 /*@access Header @*/ /* compared with NULL */ 00023 /*@access rpmfi @*/ /* compared with NULL */ 00024 00029 static inline 00030 /*@null@*/ struct TriggerFileEntry * freeTriggerFiles(/*@only@*/ /*@null@*/ struct TriggerFileEntry * p) 00031 /*@modifies p @*/ 00032 { 00033 struct TriggerFileEntry *o, *q = p; 00034 00035 while (q != NULL) { 00036 o = q; 00037 q = q->next; 00038 o->fileName = _free(o->fileName); 00039 o->script = _free(o->script); 00040 o->prog = _free(o->prog); 00041 o = _free(o); 00042 } 00043 return NULL; 00044 } 00045 00051 static inline 00052 /*@null@*/ struct Source * freeSources(/*@only@*/ /*@null@*/ struct Source * s) 00053 /*@modifies s @*/ 00054 { 00055 struct Source *r, *t = s; 00056 00057 while (t != NULL) { 00058 r = t; 00059 t = t->next; 00060 r->fullSource = _free(r->fullSource); 00061 r = _free(r); 00062 } 00063 return NULL; 00064 } 00065 00066 /*@-boundswrite@*/ 00067 int lookupPackage(Spec spec, const char *name, int flag, /*@out@*/Package *pkg) 00068 { 00069 const char *pname; 00070 const char *fullName; 00071 Package p; 00072 00073 /* "main" package */ 00074 if (name == NULL) { 00075 if (pkg) 00076 *pkg = spec->packages; 00077 return 0; 00078 } 00079 00080 /* Construct package name */ 00081 { char *n; 00082 if (flag == PART_SUBNAME) { 00083 (void) headerNVR(spec->packages->header, &pname, NULL, NULL); 00084 fullName = n = alloca(strlen(pname) + 1 + strlen(name) + 1); 00085 while (*pname != '\0') *n++ = *pname++; 00086 *n++ = '-'; 00087 } else { 00088 fullName = n = alloca(strlen(name)+1); 00089 } 00090 /*@-mayaliasunique@*/ 00091 strcpy(n, name); 00092 /*@=mayaliasunique@*/ 00093 } 00094 00095 /* Locate package with fullName */ 00096 for (p = spec->packages; p != NULL; p = p->next) { 00097 (void) headerNVR(p->header, &pname, NULL, NULL); 00098 if (pname && (! strcmp(fullName, pname))) { 00099 break; 00100 } 00101 } 00102 00103 if (pkg) 00104 /*@-dependenttrans@*/ *pkg = p; /*@=dependenttrans@*/ 00105 return ((p == NULL) ? 1 : 0); 00106 } 00107 /*@=boundswrite@*/ 00108 00109 Package newPackage(Spec spec) 00110 { 00111 Package p; 00112 Package pp; 00113 00114 p = xcalloc(1, sizeof(*p)); 00115 00116 p->header = headerNew(); 00117 p->ds = NULL; 00118 00119 p->autoProv = 1; 00120 p->autoReq = 1; 00121 00122 #if 0 00123 p->reqProv = NULL; 00124 p->triggers = NULL; 00125 p->triggerScripts = NULL; 00126 #endif 00127 00128 p->triggerFiles = NULL; 00129 00130 p->fileFile = NULL; 00131 p->fileList = NULL; 00132 00133 p->cpioList = NULL; 00134 00135 p->preInFile = NULL; 00136 p->postInFile = NULL; 00137 p->preUnFile = NULL; 00138 p->postUnFile = NULL; 00139 p->verifyFile = NULL; 00140 00141 p->specialDoc = NULL; 00142 00143 if (spec->packages == NULL) { 00144 spec->packages = p; 00145 } else { 00146 /* Always add package to end of list */ 00147 for (pp = spec->packages; pp->next != NULL; pp = pp->next) 00148 {}; 00149 pp->next = p; 00150 } 00151 p->next = NULL; 00152 00153 return p; 00154 } 00155 00156 Package freePackage(Package pkg) 00157 { 00158 if (pkg == NULL) return NULL; 00159 00160 pkg->preInFile = _free(pkg->preInFile); 00161 pkg->postInFile = _free(pkg->postInFile); 00162 pkg->preUnFile = _free(pkg->preUnFile); 00163 pkg->postUnFile = _free(pkg->postUnFile); 00164 pkg->verifyFile = _free(pkg->verifyFile); 00165 00166 pkg->header = headerFree(pkg->header); 00167 pkg->ds = rpmdsFree(pkg->ds); 00168 pkg->fileList = freeStringBuf(pkg->fileList); 00169 pkg->fileFile = _free(pkg->fileFile); 00170 if (pkg->cpioList) { 00171 rpmfi fi = pkg->cpioList; 00172 pkg->cpioList = NULL; 00173 fi = rpmfiFree(fi); 00174 } 00175 00176 pkg->specialDoc = freeStringBuf(pkg->specialDoc); 00177 pkg->triggerFiles = freeTriggerFiles(pkg->triggerFiles); 00178 00179 pkg = _free(pkg); 00180 return NULL; 00181 } 00182 00183 Package freePackages(Package packages) 00184 { 00185 Package p; 00186 00187 while ((p = packages) != NULL) { 00188 packages = p->next; 00189 p->next = NULL; 00190 p = freePackage(p); 00191 } 00192 return NULL; 00193 } 00194 00197 static inline /*@owned@*/ struct Source *findSource(Spec spec, int num, int flag) 00198 /*@*/ 00199 { 00200 struct Source *p; 00201 00202 for (p = spec->sources; p != NULL; p = p->next) 00203 if ((num == p->num) && (p->flags & flag)) return p; 00204 00205 return NULL; 00206 } 00207 00208 /*@-boundsread@*/ 00209 int parseNoSource(Spec spec, const char * field, int tag) 00210 { 00211 const char *f, *fe; 00212 const char *name; 00213 int num, flag; 00214 00215 if (tag == RPMTAG_NOSOURCE) { 00216 flag = RPMFILE_SOURCE; 00217 name = "source"; 00218 } else { 00219 flag = RPMFILE_PATCH; 00220 name = "patch"; 00221 } 00222 00223 fe = field; 00224 for (f = fe; *f != '\0'; f = fe) { 00225 struct Source *p; 00226 00227 SKIPWHITE(f); 00228 if (*f == '\0') 00229 break; 00230 fe = f; 00231 SKIPNONWHITE(fe); 00232 if (*fe != '\0') fe++; 00233 00234 if (parseNum(f, &num)) { 00235 rpmError(RPMERR_BADSPEC, _("line %d: Bad number: %s\n"), 00236 spec->lineNum, f); 00237 return RPMERR_BADSPEC; 00238 } 00239 00240 if (! (p = findSource(spec, num, flag))) { 00241 rpmError(RPMERR_BADSPEC, _("line %d: Bad no%s number: %d\n"), 00242 spec->lineNum, name, num); 00243 return RPMERR_BADSPEC; 00244 } 00245 00246 p->flags |= RPMFILE_GHOST; 00247 00248 } 00249 00250 return 0; 00251 } 00252 /*@=boundsread@*/ 00253 00254 /*@-boundswrite@*/ 00255 int addSource(Spec spec, Package pkg, const char *field, int tag) 00256 { 00257 struct Source *p; 00258 int flag = 0; 00259 const char *name = NULL; 00260 const char *mdir = NULL; 00261 char *nump; 00262 const char *fieldp = NULL; 00263 char buf[BUFSIZ]; 00264 int num = 0; 00265 00266 buf[0] = '\0'; 00267 /*@-branchstate@*/ 00268 switch (tag) { 00269 case RPMTAG_SOURCE: 00270 flag = RPMFILE_SOURCE; 00271 name = "source"; 00272 mdir = "%{_sourcedir}/"; 00273 fieldp = spec->line + (sizeof("Source")-1); 00274 break; 00275 case RPMTAG_PATCH: 00276 flag = RPMFILE_PATCH; 00277 name = "patch"; 00278 mdir = "%{_patchdir}/"; 00279 fieldp = spec->line + (sizeof("Patch")-1); 00280 break; 00281 case RPMTAG_ICON: 00282 flag = RPMFILE_ICON; 00283 name = "icon"; 00284 mdir = "%{_icondir}/"; 00285 fieldp = NULL; 00286 break; 00287 default: 00288 assert(0); 00289 /*@notreached@*/ break; 00290 } 00291 /*@=branchstate@*/ 00292 00293 /* Get the number */ 00294 if (fieldp != NULL) { 00295 /* We already know that a ':' exists, and that there */ 00296 /* are no spaces before it. */ 00297 /* This also now allows for spaces and tabs between */ 00298 /* the number and the ':' */ 00299 00300 nump = buf; 00301 while ((*fieldp != ':') && (*fieldp != ' ') && (*fieldp != '\t')) 00302 *nump++ = *fieldp++; 00303 *nump = '\0'; 00304 00305 nump = buf; 00306 SKIPSPACE(nump); 00307 if (nump == NULL || *nump == '\0') 00308 num = 0; 00309 else if (parseNum(buf, &num)) { 00310 rpmError(RPMERR_BADSPEC, _("line %d: Bad %s number: %s\n"), 00311 spec->lineNum, name, spec->line); 00312 return RPMERR_BADSPEC; 00313 } 00314 } 00315 00316 /* Create the entry and link it in */ 00317 p = xmalloc(sizeof(*p)); 00318 p->num = num; 00319 p->fullSource = xstrdup(field); 00320 p->flags = flag; 00321 p->source = strrchr(p->fullSource, '/'); 00322 if (p->source) 00323 p->source++; 00324 else 00325 p->source = p->fullSource; 00326 00327 p->next = spec->sources; 00328 spec->sources = p; 00329 00330 spec->numSources++; 00331 00332 /* XXX FIXME: need to add ICON* macros. */ 00333 if (tag != RPMTAG_ICON) { 00334 const char *body = rpmGenPath(NULL, mdir, p->source); 00335 00336 sprintf(buf, "%s%d", 00337 (flag & RPMFILE_PATCH) ? "PATCH" : "SOURCE", num); 00338 addMacro(spec->macros, buf, NULL, body, RMIL_SPEC); 00339 sprintf(buf, "%sURL%d", 00340 (flag & RPMFILE_PATCH) ? "PATCH" : "SOURCE", num); 00341 addMacro(spec->macros, buf, NULL, p->fullSource, RMIL_SPEC); 00342 body = _free(body); 00343 } 00344 00345 return 0; 00346 } 00347 /*@=boundswrite@*/ 00348 00351 static inline /*@only@*/ /*@null@*/ speclines newSl(void) 00352 /*@*/ 00353 { 00354 speclines sl = NULL; 00355 /*@-branchstate@*/ 00356 if (specedit) { 00357 sl = xmalloc(sizeof(*sl)); 00358 sl->sl_lines = NULL; 00359 sl->sl_nalloc = 0; 00360 sl->sl_nlines = 0; 00361 } 00362 /*@=branchstate@*/ 00363 return sl; 00364 } 00365 00368 /*@-boundswrite@*/ 00369 static inline /*@null@*/ speclines freeSl(/*@only@*/ /*@null@*/ speclines sl) 00370 /*@modifies sl @*/ 00371 { 00372 int i; 00373 if (sl == NULL) return NULL; 00374 for (i = 0; i < sl->sl_nlines; i++) 00375 /*@-unqualifiedtrans@*/ 00376 sl->sl_lines[i] = _free(sl->sl_lines[i]); 00377 /*@=unqualifiedtrans@*/ 00378 sl->sl_lines = _free(sl->sl_lines); 00379 return _free(sl); 00380 } 00381 /*@=boundswrite@*/ 00382 00385 static inline /*@only@*/ /*@null@*/ spectags newSt(void) 00386 /*@*/ 00387 { 00388 spectags st = NULL; 00389 /*@-branchstate@*/ 00390 if (specedit) { 00391 st = xmalloc(sizeof(*st)); 00392 st->st_t = NULL; 00393 st->st_nalloc = 0; 00394 st->st_ntags = 0; 00395 } 00396 /*@=branchstate@*/ 00397 return st; 00398 } 00399 00402 static inline /*@null@*/ spectags freeSt(/*@only@*/ /*@null@*/ spectags st) 00403 /*@modifies st @*/ 00404 { 00405 int i; 00406 if (st == NULL) return NULL; 00407 for (i = 0; i < st->st_ntags; i++) { 00408 spectag t = st->st_t + i; 00409 t->t_lang = _free(t->t_lang); 00410 t->t_msgid = _free(t->t_msgid); 00411 } 00412 st->st_t = _free(st->st_t); 00413 return _free(st); 00414 } 00415 00416 Spec newSpec(void) 00417 { 00418 Spec spec = xcalloc(1, sizeof(*spec)); 00419 00420 spec->specFile = NULL; 00421 00422 spec->sl = newSl(); 00423 spec->st = newSt(); 00424 00425 spec->fileStack = NULL; 00426 /*@-boundswrite@*/ 00427 spec->lbuf[0] = '\0'; 00428 /*@=boundswrite@*/ 00429 spec->line = spec->lbuf; 00430 spec->nextline = NULL; 00431 spec->nextpeekc = '\0'; 00432 spec->lineNum = 0; 00433 spec->readStack = xcalloc(1, sizeof(*spec->readStack)); 00434 spec->readStack->next = NULL; 00435 spec->readStack->reading = 1; 00436 00437 spec->rootURL = NULL; 00438 spec->prep = NULL; 00439 spec->build = NULL; 00440 spec->install = NULL; 00441 spec->check = NULL; 00442 spec->clean = NULL; 00443 00444 spec->sources = NULL; 00445 spec->packages = NULL; 00446 spec->noSource = 0; 00447 spec->numSources = 0; 00448 00449 spec->sourceRpmName = NULL; 00450 spec->sourcePkgId = NULL; 00451 spec->sourceHeader = headerNew(); 00452 spec->sourceCpioList = NULL; 00453 00454 spec->buildSubdir = NULL; 00455 00456 spec->passPhrase = NULL; 00457 spec->timeCheck = 0; 00458 spec->cookie = NULL; 00459 00460 spec->BANames = NULL; 00461 spec->BACount = 0; 00462 spec->recursing = 0; 00463 spec->BASpecs = NULL; 00464 00465 spec->force = 0; 00466 spec->anyarch = 0; 00467 00468 /*@i@*/ spec->macros = rpmGlobalMacroContext; 00469 00470 spec->_parseRCPOT = parseRCPOT; /* XXX hack around backward linkage. */ 00471 00472 return spec; 00473 } 00474 00475 Spec freeSpec(Spec spec) 00476 { 00477 struct ReadLevelEntry *rl; 00478 00479 if (spec == NULL) return NULL; 00480 00481 spec->sl = freeSl(spec->sl); 00482 spec->st = freeSt(spec->st); 00483 00484 spec->prep = freeStringBuf(spec->prep); 00485 spec->build = freeStringBuf(spec->build); 00486 spec->install = freeStringBuf(spec->install); 00487 spec->check = freeStringBuf(spec->check); 00488 spec->clean = freeStringBuf(spec->clean); 00489 00490 spec->buildSubdir = _free(spec->buildSubdir); 00491 spec->rootURL = _free(spec->rootURL); 00492 spec->specFile = _free(spec->specFile); 00493 00494 #ifdef DEAD 00495 { struct OpenFileInfo *ofi; 00496 while (spec->fileStack) { 00497 ofi = spec->fileStack; 00498 spec->fileStack = ofi->next; 00499 ofi->next = NULL; 00500 ofi->fileName = _free(ofi->fileName); 00501 ofi = _free(ofi); 00502 } 00503 } 00504 #else 00505 closeSpec(spec); 00506 #endif 00507 00508 while (spec->readStack) { 00509 rl = spec->readStack; 00510 /*@-dependenttrans@*/ 00511 spec->readStack = rl->next; 00512 /*@=dependenttrans@*/ 00513 rl->next = NULL; 00514 rl = _free(rl); 00515 } 00516 00517 spec->sourceRpmName = _free(spec->sourceRpmName); 00518 spec->sourcePkgId = _free(spec->sourcePkgId); 00519 spec->sourceHeader = headerFree(spec->sourceHeader); 00520 00521 if (spec->sourceCpioList) { 00522 rpmfi fi = spec->sourceCpioList; 00523 spec->sourceCpioList = NULL; 00524 fi = rpmfiFree(fi); 00525 } 00526 00527 if (!spec->recursing) { 00528 /*@-boundswrite@*/ 00529 if (spec->BASpecs != NULL) 00530 while (spec->BACount--) { 00531 /*@-unqualifiedtrans@*/ 00532 spec->BASpecs[spec->BACount] = 00533 freeSpec(spec->BASpecs[spec->BACount]); 00534 /*@=unqualifiedtrans@*/ 00535 } 00536 /*@=boundswrite@*/ 00537 /*@-compdef@*/ 00538 spec->BASpecs = _free(spec->BASpecs); 00539 /*@=compdef@*/ 00540 } 00541 spec->BANames = _free(spec->BANames); 00542 00543 spec->passPhrase = _free(spec->passPhrase); 00544 spec->cookie = _free(spec->cookie); 00545 00546 spec->sources = freeSources(spec->sources); 00547 spec->packages = freePackages(spec->packages); 00548 00549 spec = _free(spec); 00550 00551 return spec; 00552 } 00553 00554 /*@only@*/ 00555 struct OpenFileInfo * newOpenFileInfo(void) 00556 { 00557 struct OpenFileInfo *ofi; 00558 00559 ofi = xmalloc(sizeof(*ofi)); 00560 ofi->fd = NULL; 00561 ofi->fileName = NULL; 00562 ofi->lineNum = 0; 00563 /*@-boundswrite@*/ 00564 ofi->readBuf[0] = '\0'; 00565 /*@=boundswrite@*/ 00566 ofi->readPtr = NULL; 00567 ofi->next = NULL; 00568 00569 return ofi; 00570 } 00571 00576 static void 00577 printNewSpecfile(Spec spec) 00578 /*@globals fileSystem @*/ 00579 /*@modifies spec->sl->sl_lines[], fileSystem @*/ 00580 { 00581 Header h; 00582 speclines sl = spec->sl; 00583 spectags st = spec->st; 00584 const char * msgstr = NULL; 00585 int i, j; 00586 00587 if (sl == NULL || st == NULL) 00588 return; 00589 00590 /*@-branchstate@*/ 00591 for (i = 0; i < st->st_ntags; i++) { 00592 spectag t = st->st_t + i; 00593 const char * tn = tagName(t->t_tag); 00594 const char * errstr; 00595 char fmt[1024]; 00596 00597 fmt[0] = '\0'; 00598 if (t->t_msgid == NULL) 00599 h = spec->packages->header; 00600 else { 00601 Package pkg; 00602 char *fe; 00603 00604 /*@-bounds@*/ 00605 strcpy(fmt, t->t_msgid); 00606 for (fe = fmt; *fe && *fe != '('; fe++) 00607 {} ; 00608 if (*fe == '(') *fe = '\0'; 00609 /*@=bounds@*/ 00610 h = NULL; 00611 for (pkg = spec->packages; pkg != NULL; pkg = pkg->next) { 00612 const char *pkgname; 00613 h = pkg->header; 00614 (void) headerNVR(h, &pkgname, NULL, NULL); 00615 if (!strcmp(pkgname, fmt)) 00616 /*@innerbreak@*/ break; 00617 } 00618 if (pkg == NULL || h == NULL) 00619 h = spec->packages->header; 00620 } 00621 00622 if (h == NULL) 00623 continue; 00624 00625 fmt[0] = '\0'; 00626 /*@-boundswrite@*/ 00627 (void) stpcpy( stpcpy( stpcpy( fmt, "%{"), tn), "}"); 00628 /*@=boundswrite@*/ 00629 msgstr = _free(msgstr); 00630 00631 /* XXX this should use queryHeader(), but prints out tn as well. */ 00632 msgstr = headerSprintf(h, fmt, rpmTagTable, rpmHeaderFormats, &errstr); 00633 if (msgstr == NULL) { 00634 rpmError(RPMERR_QFMT, _("can't query %s: %s\n"), tn, errstr); 00635 return; 00636 } 00637 00638 /*@-boundswrite@*/ 00639 switch(t->t_tag) { 00640 case RPMTAG_SUMMARY: 00641 case RPMTAG_GROUP: 00642 /*@-unqualifiedtrans@*/ 00643 sl->sl_lines[t->t_startx] = _free(sl->sl_lines[t->t_startx]); 00644 /*@=unqualifiedtrans@*/ 00645 if (t->t_lang && strcmp(t->t_lang, RPMBUILD_DEFAULT_LANG)) 00646 continue; 00647 { char *buf = xmalloc(strlen(tn) + sizeof(": ") + strlen(msgstr)); 00648 (void) stpcpy( stpcpy( stpcpy(buf, tn), ": "), msgstr); 00649 sl->sl_lines[t->t_startx] = buf; 00650 } 00651 /*@switchbreak@*/ break; 00652 case RPMTAG_DESCRIPTION: 00653 for (j = 1; j < t->t_nlines; j++) { 00654 if (*sl->sl_lines[t->t_startx + j] == '%') 00655 /*@innercontinue@*/ continue; 00656 /*@-unqualifiedtrans@*/ 00657 sl->sl_lines[t->t_startx + j] = 00658 _free(sl->sl_lines[t->t_startx + j]); 00659 /*@=unqualifiedtrans@*/ 00660 } 00661 if (t->t_lang && strcmp(t->t_lang, RPMBUILD_DEFAULT_LANG)) { 00662 sl->sl_lines[t->t_startx] = _free(sl->sl_lines[t->t_startx]); 00663 continue; 00664 } 00665 sl->sl_lines[t->t_startx + 1] = xstrdup(msgstr); 00666 if (t->t_nlines > 2) 00667 sl->sl_lines[t->t_startx + 2] = xstrdup("\n\n"); 00668 /*@switchbreak@*/ break; 00669 } 00670 /*@=boundswrite@*/ 00671 } 00672 /*@=branchstate@*/ 00673 msgstr = _free(msgstr); 00674 00675 for (i = 0; i < sl->sl_nlines; i++) { 00676 const char * s = sl->sl_lines[i]; 00677 if (s == NULL) 00678 continue; 00679 printf("%s", s); 00680 if (strchr(s, '\n') == NULL && s[strlen(s)-1] != '\n') 00681 printf("\n"); 00682 } 00683 } 00684 00693 static int initSourceHeaderScriptlet(Header h, 00694 rpmTag progTag, rpmTag scriptTag, StringBuf sb) 00695 /*@modifies h @*/ 00696 { 00697 int xx; 00698 00699 if (progTag !=(rpmTag) 0) { 00700 static const char prog[] = "/bin/sh"; /* XXX FIXME */ 00701 xx = headerAddEntry(h, progTag, RPM_STRING_TYPE, prog, 1); 00702 } 00703 00704 if (scriptTag != (rpmTag)0 && sb != NULL) { 00705 xx = headerAddEntry(h, scriptTag, RPM_STRING_TYPE, getStringBuf(sb), 1); 00706 } 00707 return 0; 00708 } 00709 00715 static int initSourceHeaderScriptlets(Spec spec) 00716 /*@modifies spec->sourceHeader @*/ 00717 { 00718 int xx; 00719 00720 if (spec->prep != NULL) 00721 xx = initSourceHeaderScriptlet(spec->sourceHeader, 00722 RPMTAG_Buildprepprog, RPMTAG_Buildprep, spec->prep); 00723 if (spec->build != NULL) 00724 xx = initSourceHeaderScriptlet(spec->sourceHeader, 00725 RPMTAG_Buildbuildprog, RPMTAG_Buildbuild, spec->build); 00726 if (spec->install != NULL) 00727 xx = initSourceHeaderScriptlet(spec->sourceHeader, 00728 RPMTAG_Buildinstallprog, RPMTAG_Buildinstall, spec->install); 00729 if (spec->check != NULL) 00730 xx = initSourceHeaderScriptlet(spec->sourceHeader, 00731 RPMTAG_Buildcheckprog, RPMTAG_Buildcheck, spec->check); 00732 if (spec->clean != NULL) 00733 xx = initSourceHeaderScriptlet(spec->sourceHeader, 00734 RPMTAG_Buildcleanprog, RPMTAG_Buildclean, spec->clean); 00735 00736 return 0; 00737 } 00738 00747 static int _specQuery(rpmts ts, QVA_t qva, const char *specName, 00748 /*@null@*/ const char *target) 00749 /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/ 00750 /*@modifies rpmGlobalMacroContext, fileSystem, internalState @*/ 00751 { 00752 Spec spec = NULL; 00753 Package pkg; 00754 int res = 1; /* assume error */ 00755 int anyarch = (target == NULL) ? 1 : 0; 00756 char * passPhrase = ""; 00757 int recursing = 0; 00758 char *cookie = NULL; 00759 int force = 1; 00760 int verify = 0; 00761 int xx; 00762 00763 /*@-mods@*/ /* FIX: make spec abstract */ 00764 if (parseSpec(ts, specName, "/", recursing, passPhrase, 00765 cookie, anyarch, force, verify) 00766 || (spec = rpmtsSetSpec(ts, NULL)) == NULL) 00767 { 00768 rpmError(RPMERR_QUERY, 00769 _("query of specfile %s failed, can't parse\n"), 00770 specName); 00771 goto exit; 00772 } 00773 /*@=mods@*/ 00774 00775 res = 0; 00776 if (specedit) { 00777 printNewSpecfile(spec); 00778 goto exit; 00779 } 00780 00781 switch (qva->qva_source) { 00782 case RPMQV_SPECSRPM: 00783 xx = initSourceHeader(spec, NULL); 00784 xx = initSourceHeaderScriptlets(spec); 00785 xx = qva->qva_showPackage(qva, ts, spec->sourceHeader); 00786 break; 00787 default: 00788 case RPMQV_SPECFILE: 00789 for (pkg = spec->packages; pkg != NULL; pkg = pkg->next) { 00790 /* If no target was specified, display all packages. 00791 * Packages with empty file lists are not produced. 00792 */ 00793 /* XXX DIEDIEDIE: this logic looks flawed. */ 00794 if (target == NULL || pkg->fileList != NULL) 00795 xx = qva->qva_showPackage(qva, ts, pkg->header); 00796 } 00797 break; 00798 } 00799 00800 exit: 00801 spec = freeSpec(spec); 00802 return res; 00803 } 00804 00805 int rpmspecQuery(rpmts ts, QVA_t qva, const char * arg) 00806 { 00807 int res = 1; 00808 const char * targets = rpmcliTargets; 00809 char *target; 00810 const char * t; 00811 const char * te; 00812 const char * rcfile = rpmcliRcfile; 00813 int nqueries = 0; 00814 00815 if (qva->qva_showPackage == NULL) 00816 goto exit; 00817 00818 if (targets == NULL) { 00819 res = _specQuery(ts, qva, arg, NULL); 00820 nqueries++; 00821 goto exit; 00822 } 00823 00824 rpmMessage(RPMMESS_DEBUG, 00825 D_("Query specfile for platform(s): %s\n"), targets); 00826 for (t = targets; *t != '\0'; t = te) { 00827 /* Parse out next target platform. */ 00828 if ((te = strchr(t, ',')) == NULL) 00829 te = t + strlen(t); 00830 target = alloca(te-t+1); 00831 strncpy(target, t, (te-t)); 00832 target[te-t] = '\0'; 00833 if (*te != '\0') 00834 te++; 00835 00836 /* Query spec for this target platform. */ 00837 rpmMessage(RPMMESS_DEBUG, D_(" target platform: %s\n"), target); 00838 /* Read in configuration for target. */ 00839 if (t != targets) { 00840 rpmFreeMacros(NULL); 00841 rpmFreeRpmrc(); 00842 (void) rpmReadConfigFiles(rcfile, target); 00843 } 00844 res = _specQuery(ts, qva, arg, target); 00845 nqueries++; 00846 if (res) break; 00847 } 00848 00849 exit: 00850 /* Restore original configuration. */ 00851 if (nqueries > 1) { 00852 t = targets; 00853 if ((te = strchr(t, ',')) == NULL) 00854 te = t + strlen(t); 00855 target = alloca(te-t+1); 00856 strncpy(target, t, (te-t)); 00857 target[te-t] = '\0'; 00858 if (*te != '\0') 00859 te++; 00860 rpmFreeMacros(NULL); 00861 rpmFreeRpmrc(); 00862 (void) rpmReadConfigFiles(rcfile, target); 00863 } 00864 return res; 00865 }