rpm 5.3.7
|
00001 00006 #include "system.h" 00007 00008 #include <rpmio.h> 00009 #include <rpmiotypes.h> 00010 #include <rpmlog.h> 00011 #include <rpmpgp.h> 00012 00013 #include "buildio.h" 00014 #include "rpmds.h" 00015 #include "rpmfi.h" 00016 #include "rpmts.h" 00017 00018 #include "rpmlua.h" 00019 00020 #include "debug.h" 00021 00022 /*@unchecked@*/ 00023 int _pkg_debug; 00024 00025 /*@unchecked@*/ 00026 int _spec_debug; 00027 00028 /*@-redecl@*/ 00029 extern int specedit; 00030 /*@=redecl@*/ 00031 00032 #define SKIPWHITE(_x) {while(*(_x) && (xisspace(*_x) || *(_x) == ',')) (_x)++;} 00033 #define SKIPNONWHITE(_x){while(*(_x) &&!(xisspace(*_x) || *(_x) == ',')) (_x)++;} 00034 00035 /*@access rpmluav @*/ 00036 00041 static inline 00042 /*@null@*/ struct TriggerFileEntry * freeTriggerFiles(/*@only@*/ /*@null@*/ struct TriggerFileEntry * p) 00043 /*@modifies p @*/ 00044 { 00045 struct TriggerFileEntry *o, *q = p; 00046 00047 while (q != NULL) { 00048 o = q; 00049 q = q->next; 00050 o->fileName = _free(o->fileName); 00051 o->script = _free(o->script); 00052 o->prog = _free(o->prog); 00053 o = _free(o); 00054 } 00055 return NULL; 00056 } 00057 00063 static inline 00064 /*@null@*/ struct Source * freeSources(/*@only@*/ /*@null@*/ struct Source * s) 00065 /*@modifies s @*/ 00066 { 00067 struct Source *r, *t = s; 00068 00069 while (t != NULL) { 00070 r = t; 00071 t = t->next; 00072 r->fullSource = _free(r->fullSource); 00073 r = _free(r); 00074 } 00075 return NULL; 00076 } 00077 00078 rpmRC lookupPackage(Spec spec, const char *name, int flag, /*@out@*/Package *pkgp) 00079 { 00080 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he)); 00081 char *NV = NULL; 00082 char *N = NULL; 00083 char *V = NULL; 00084 Package p; 00085 Package lastp = spec->packages; 00086 rpmRC rc = RPMRC_OK; 00087 int xx; 00088 00089 if (lastp == NULL) /* XXX segfault avoidance */ 00090 goto exit; 00091 /* "main" package */ 00092 if (name == NULL) 00093 goto exit; 00094 00095 /* Construct package name */ 00096 if (flag == PART_SUBNAME) { 00097 he->tag = RPMTAG_NAME; 00098 xx = headerGet(spec->packages->header, he, 0); 00099 assert(xx != 0 && he->p.str != NULL); 00100 N = rpmExpand(he->p.str, "-", name, NULL); 00101 he->p.ptr = _free(he->p.ptr); 00102 } else { 00103 N = xstrdup(name); 00104 /* XXX restrict V to leading digit to prevent NV split ambiguity. */ 00105 if ((V = strrchr(N, '-')) != NULL && xisdigit(V[1])) { 00106 NV = xstrdup(N); 00107 *V++ = '\0'; 00108 } else 00109 V = NULL; 00110 } 00111 00112 /* Match last package with same N or same {N,V} */ 00113 lastp = NULL; 00114 for (p = spec->packages; p != NULL; p = p->next) { 00115 char *nv, *n, *v; 00116 nv = n = v = NULL; 00117 he->tag = RPMTAG_NAME; 00118 xx = headerGet(p->header, he, 0); 00119 if (xx && he->p.str != NULL) { 00120 n = (char *) he->p.str; 00121 he->p.str = NULL; 00122 } 00123 if (NV != NULL) { 00124 he->tag = RPMTAG_VERSION; 00125 xx = headerGet(p->header, he, 0); 00126 if (xx && he->p.str != NULL) { 00127 v = (char *) he->p.str; 00128 he->p.str = NULL; 00129 nv = rpmExpand(n, "-", v, NULL); 00130 } 00131 } 00132 00133 if (NV == NULL) { 00134 if (!strcmp(N, n)) 00135 lastp = p; 00136 } else { 00137 if (!strcmp(NV, nv) || !strcmp(NV, n) 00138 || (!strcmp(N, n) && (V == NULL || !strcmp(V, v)))) 00139 lastp = p; 00140 } 00141 /*@-usereleased@*/ 00142 n = _free(n); 00143 v = _free(v); 00144 nv = _free(nv); 00145 /*@=usereleased@*/ 00146 } 00147 rc = (lastp == NULL ? RPMRC_FAIL : RPMRC_OK); 00148 NV = _free(NV); 00149 N = _free(N); 00150 00151 exit: 00152 if (pkgp) 00153 /*@-dependenttrans@*/ *pkgp = lastp; /*@=dependenttrans@*/ 00154 return rc; 00155 } 00156 00157 static void pkgFini(void * _pkg) 00158 /*@modifies _pkg @*/ 00159 { 00160 Package pkg = _pkg; 00161 00162 if (pkg == NULL) return; /* XXX assert? */ 00163 00164 pkg->preInFile = _free(pkg->preInFile); 00165 pkg->postInFile = _free(pkg->postInFile); 00166 pkg->preUnFile = _free(pkg->preUnFile); 00167 pkg->postUnFile = _free(pkg->postUnFile); 00168 pkg->verifyFile = _free(pkg->verifyFile); 00169 pkg->sanityCheckFile = _free(pkg->sanityCheckFile); 00170 00171 (void)headerFree(pkg->header); 00172 pkg->header = NULL; 00173 (void)rpmdsFree(pkg->ds); 00174 pkg->ds = NULL; 00175 pkg->fileList = rpmiobFree(pkg->fileList); 00176 pkg->fileFile = _free(pkg->fileFile); 00177 if (pkg->fi != NULL) { 00178 rpmfi fi = pkg->fi; 00179 pkg->fi = NULL; 00180 fi = rpmfiFree(fi); 00181 } 00182 00183 pkg->specialDoc = rpmiobFree(pkg->specialDoc); 00184 pkg->triggerFiles = freeTriggerFiles(pkg->triggerFiles); 00185 } 00186 00187 /*@unchecked@*/ /*@only@*/ /*@null@*/ 00188 rpmioPool _pkgPool; 00189 00190 static Package pkgGetPool(rpmioPool pool) 00191 { 00192 Package pkg; 00193 00194 if (_pkgPool == NULL) { 00195 _pkgPool = rpmioNewPool("pkg", sizeof(*pkg), -1, _pkg_debug, 00196 NULL, NULL, pkgFini); 00197 pool = _pkgPool; 00198 } 00199 pkg = (Package) rpmioGetPool(pool, sizeof(*pkg)); 00200 memset(((char *)pkg)+sizeof(pkg->_item), 0, sizeof(*pkg)-sizeof(pkg->_item)); 00201 return pkg; 00202 } 00203 00204 Package newPackage(/*@unused@*/ Spec spec) 00205 { 00206 Package pkg = pkgGetPool(_pkgPool); 00207 00208 pkg->header = headerNew(); 00209 pkg->ds = NULL; 00210 00211 pkg->autoProv = ((_rpmbuildFlags & 0x1) != 0); 00212 pkg->autoReq = ((_rpmbuildFlags & 0x2) != 0); 00213 00214 #if 0 00215 pkg->reqProv = NULL; 00216 pkg->triggers = NULL; 00217 pkg->triggerScripts = NULL; 00218 #endif 00219 00220 pkg->triggerFiles = NULL; 00221 00222 pkg->fileFile = NULL; 00223 pkg->fileList = NULL; 00224 00225 pkg->fi = NULL; 00226 00227 pkg->preInFile = NULL; 00228 pkg->postInFile = NULL; 00229 pkg->preUnFile = NULL; 00230 pkg->postUnFile = NULL; 00231 pkg->verifyFile = NULL; 00232 pkg->sanityCheckFile = NULL; 00233 00234 pkg->specialDoc = NULL; 00235 00236 pkg->next = NULL; 00237 00238 return (Package)rpmioLinkPoolItem((rpmioItem)pkg, __FUNCTION__, __FILE__, __LINE__); 00239 } 00240 00241 Package freePackages(Package packages) 00242 { 00243 Package p; 00244 00245 while ((p = packages) != NULL) { 00246 packages = p->next; 00247 p->next = NULL; 00248 p = freePackage(p); 00249 } 00250 return NULL; 00251 } 00252 00255 static inline /*@owned@*/ struct Source *findSource(Spec spec, rpmuint32_t num, int flag) 00256 /*@*/ 00257 { 00258 struct Source *p; 00259 00260 for (p = spec->sources; p != NULL; p = p->next) 00261 if ((num == p->num) && (p->flags & flag)) return p; 00262 00263 return NULL; 00264 } 00265 00268 int SpecSourceCount(Spec spec) 00269 { 00270 return spec->numSources; 00271 } 00272 00275 SpecSource getSource(Spec spec, int num) 00276 /* @ */ 00277 { 00278 struct Source *p = spec->sources; 00279 int i; 00280 00281 for (i = 0; i < num; i++) 00282 if ((p = p->next) == NULL) return NULL; 00283 00284 /*@-usereleased@*/ 00285 return p; 00286 /*@=usereleased@*/ 00287 } 00288 00291 const char * specSourceName(SpecSource source) 00292 { 00293 return source->source; 00294 } 00295 00298 const char * specFullSourceName(SpecSource source) 00299 { 00300 return source->fullSource; 00301 } 00302 00305 int specSourceNum(SpecSource source) 00306 { 00307 return source->num; 00308 } 00309 00312 int specSourceFlags(SpecSource source) 00313 { 00314 return source->flags; 00315 } 00316 00317 int parseNoSource(Spec spec, const char * field, rpmTag tag) 00318 { 00319 const char *f, *fe; 00320 const char *name; 00321 rpmuint32_t num, flag; 00322 00323 if (tag == RPMTAG_NOSOURCE) { 00324 flag = RPMFILE_SOURCE; 00325 name = "source"; 00326 } else { 00327 flag = RPMFILE_PATCH; 00328 name = "patch"; 00329 } 00330 00331 fe = field; 00332 for (f = fe; *f != '\0'; f = fe) { 00333 struct Source *p; 00334 00335 SKIPWHITE(f); 00336 if (*f == '\0') 00337 break; 00338 fe = f; 00339 SKIPNONWHITE(fe); 00340 if (*fe != '\0') fe++; 00341 00342 if (parseNum(f, &num)) { 00343 rpmlog(RPMLOG_ERR, _("line %d: Bad number: %s\n"), 00344 spec->lineNum, f); 00345 return RPMRC_FAIL; 00346 } 00347 00348 if (! (p = findSource(spec, num, flag))) { 00349 rpmlog(RPMLOG_ERR, _("line %d: Bad no%s number: %d\n"), 00350 spec->lineNum, name, num); 00351 return RPMRC_FAIL; 00352 } 00353 00354 p->flags |= RPMFILE_GHOST; 00355 00356 } 00357 00358 return RPMRC_OK; 00359 } 00360 00361 int addSource(Spec spec, /*@unused@*/ Package pkg, 00362 const char *field, rpmTag tag) 00363 { 00364 struct Source *p; 00365 #if defined(RPM_VENDOR_OPENPKG) /* regular-ordered-sources */ 00366 struct Source *p_last; 00367 #endif 00368 int flag = 0; 00369 const char *name = NULL; 00370 const char *mdir = NULL; 00371 const char *fieldp = NULL; 00372 char buf[BUFSIZ]; 00373 uint32_t num = 0; 00374 00375 buf[0] = '\0'; 00376 switch (tag) { 00377 case RPMTAG_SOURCE: 00378 flag = RPMFILE_SOURCE; 00379 name = "source"; 00380 fieldp = spec->line + strlen(name); 00381 break; 00382 case RPMTAG_PATCH: 00383 flag = RPMFILE_PATCH; 00384 name = "patch"; 00385 fieldp = spec->line + strlen(name); 00386 break; 00387 case RPMTAG_ICON: 00388 flag = RPMFILE_ICON; 00389 name = "icon"; 00390 fieldp = NULL; 00391 break; 00392 default: 00393 assert(0); 00394 /*@notreached@*/ break; 00395 } 00396 #if !defined(RPM_VENDOR_OPENPKG) /* splitted-source-directory */ 00397 mdir = getSourceDir(flag); 00398 assert(mdir != NULL); 00399 #endif 00400 00401 /* Get the number */ 00402 if (fieldp != NULL) { 00403 char * end = NULL; 00404 00405 num = strtoul(fieldp, &end, 10); 00406 SKIPSPACE(end); 00407 if (*end != ':') { 00408 rpmlog(RPMLOG_ERR, _("line %d: No ':' terminator: %s\n"), 00409 spec->lineNum, spec->line); 00410 return RPMRC_FAIL; 00411 } 00412 } 00413 00414 /* Check whether tags of the same number haven't already been defined */ 00415 for (p = spec->sources; p != NULL; p = p->next) { 00416 if ( p->num != num ) continue; 00417 if ((tag == RPMTAG_SOURCE && p->flags == RPMFILE_SOURCE) || 00418 (tag == RPMTAG_PATCH && p->flags == RPMFILE_PATCH)) { 00419 rpmlog(RPMLOG_ERR, _("%s %d defined multiple times\n"), name, num); 00420 return RPMRC_FAIL; 00421 } 00422 } 00423 00424 /* Create the entry and link it in */ 00425 p = xmalloc(sizeof(*p)); 00426 p->num = num; 00427 p->fullSource = xstrdup(field); 00428 p->flags = flag; 00429 p->source = strrchr(p->fullSource, '/'); 00430 if (p->source) 00431 p->source++; 00432 else 00433 p->source = p->fullSource; 00434 00435 #if defined(RPM_VENDOR_OPENPKG) /* regular-ordered-sources */ 00436 p->next = NULL; 00437 p_last = spec->sources; 00438 while (p_last != NULL && p_last->next != NULL) 00439 p_last = p_last->next; 00440 if (p_last != NULL) 00441 p_last->next = p; 00442 else 00443 spec->sources = p; 00444 #else 00445 p->next = spec->sources; 00446 spec->sources = p; 00447 #endif 00448 00449 spec->numSources++; 00450 00451 /* XXX FIXME: need to add ICON* macros. */ 00452 #if defined(RPM_VENDOR_OPENPKG) /* splitted-source-directory */ 00453 mdir = getSourceDir(flag, p->source); 00454 #endif 00455 if (tag != RPMTAG_ICON) { 00456 const char *body = rpmGenPath(NULL, mdir, p->source); 00457 00458 sprintf(buf, "%s%d", 00459 (flag & RPMFILE_PATCH) ? "PATCH" : "SOURCE", num); 00460 addMacro(spec->macros, buf, NULL, body, RMIL_SPEC); 00461 sprintf(buf, "%sURL%d", 00462 (flag & RPMFILE_PATCH) ? "PATCH" : "SOURCE", num); 00463 addMacro(spec->macros, buf, NULL, p->fullSource, RMIL_SPEC); 00464 #ifdef WITH_LUA 00465 if (!spec->recursing) { 00466 rpmlua lua = NULL; /* global state */ 00467 const char * what = (flag & RPMFILE_PATCH) ? "patches" : "sources"; 00468 rpmluav var = rpmluavNew(); 00469 00470 rpmluaPushTable(lua, what); 00471 rpmluavSetListMode(var, 1); 00472 rpmluavSetValue(var, RPMLUAV_STRING, body); 00473 rpmluaSetVar(lua, var); 00474 /*@-moduncon@*/ 00475 var = (rpmluav) rpmluavFree(var); 00476 /*@=moduncon@*/ 00477 rpmluaPop(lua); 00478 } 00479 #endif 00480 body = _free(body); 00481 } 00482 00483 return RPMRC_OK; 00484 } 00485 00488 static inline /*@only@*/ /*@null@*/ speclines newSl(void) 00489 /*@*/ 00490 { 00491 speclines sl = NULL; 00492 if (specedit) { 00493 sl = xmalloc(sizeof(*sl)); 00494 sl->sl_lines = NULL; 00495 sl->sl_nalloc = 0; 00496 sl->sl_nlines = 0; 00497 } 00498 return sl; 00499 } 00500 00503 static inline /*@null@*/ speclines freeSl(/*@only@*/ /*@null@*/ speclines sl) 00504 /*@modifies sl @*/ 00505 { 00506 int i; 00507 if (sl == NULL) return NULL; 00508 for (i = 0; i < sl->sl_nlines; i++) 00509 /*@-unqualifiedtrans@*/ 00510 sl->sl_lines[i] = _free(sl->sl_lines[i]); 00511 /*@=unqualifiedtrans@*/ 00512 sl->sl_lines = _free(sl->sl_lines); 00513 return _free(sl); 00514 } 00515 00518 static inline /*@only@*/ /*@null@*/ spectags newSt(void) 00519 /*@*/ 00520 { 00521 spectags st = NULL; 00522 if (specedit) { 00523 st = xmalloc(sizeof(*st)); 00524 st->st_t = NULL; 00525 st->st_nalloc = 0; 00526 st->st_ntags = 0; 00527 } 00528 return st; 00529 } 00530 00533 static inline /*@null@*/ spectags freeSt(/*@only@*/ /*@null@*/ spectags st) 00534 /*@modifies st @*/ 00535 { 00536 int i; 00537 if (st == NULL) return NULL; 00538 for (i = 0; i < st->st_ntags; i++) { 00539 spectag t = st->st_t + i; 00540 t->t_lang = _free(t->t_lang); 00541 t->t_msgid = _free(t->t_msgid); 00542 } 00543 st->st_t = _free(st->st_t); 00544 return _free(st); 00545 } 00546 00547 static void specFini(void * _spec) 00548 /*@modifies _spec @*/ 00549 { 00550 Spec spec = _spec; 00551 struct ReadLevelEntry *rl; 00552 00553 if (spec == NULL) return; /* XXX assert? */ 00554 00555 spec->lbuf = _free(spec->lbuf); 00556 00557 spec->sl = freeSl(spec->sl); 00558 spec->st = freeSt(spec->st); 00559 00560 spec->prep = rpmiobFree(spec->prep); 00561 spec->build = rpmiobFree(spec->build); 00562 spec->install = rpmiobFree(spec->install); 00563 spec->check = rpmiobFree(spec->check); 00564 spec->clean = rpmiobFree(spec->clean); 00565 spec->foo = tagStoreFree(spec->foo, spec->nfoo); 00566 spec->nfoo = 0; 00567 00568 spec->buildSubdir = _free(spec->buildSubdir); 00569 spec->rootURL = _free(spec->rootURL); 00570 spec->specFile = _free(spec->specFile); 00571 00572 closeSpec(spec); 00573 00574 while (spec->readStack) { 00575 rl = spec->readStack; 00576 /*@-dependenttrans@*/ 00577 spec->readStack = rl->next; 00578 /*@=dependenttrans@*/ 00579 rl->next = NULL; 00580 rl = _free(rl); 00581 } 00582 00583 spec->sourceRpmName = _free(spec->sourceRpmName); 00584 spec->sourcePkgId = _free(spec->sourcePkgId); 00585 spec->sourceHeader = headerFree(spec->sourceHeader); 00586 00587 if (spec->fi != NULL) { 00588 rpmfi fi = spec->fi; 00589 spec->fi = NULL; 00590 fi = rpmfiFree(fi); 00591 } 00592 00593 if (!spec->recursing) { 00594 if (spec->BASpecs != NULL) 00595 while (spec->BACount--) { 00596 /*@-unqualifiedtrans@*/ 00597 spec->BASpecs[spec->BACount] = 00598 freeSpec(spec->BASpecs[spec->BACount]); 00599 /*@=unqualifiedtrans@*/ 00600 } 00601 /*@-compdef@*/ 00602 spec->BASpecs = _free(spec->BASpecs); 00603 /*@=compdef@*/ 00604 } 00605 spec->BANames = _free(spec->BANames); 00606 00607 spec->passPhrase = _free(spec->passPhrase); 00608 spec->cookie = _free(spec->cookie); 00609 00610 #ifdef WITH_LUA 00611 { rpmlua lua = NULL; /* global state */ 00612 rpmluaDelVar(lua, "patches"); 00613 rpmluaDelVar(lua, "sources"); 00614 } 00615 #endif 00616 00617 spec->sources = freeSources(spec->sources); 00618 00619 spec->dig = pgpDigFree(spec->dig); 00620 spec->packages = freePackages(spec->packages); 00621 00622 } 00623 00624 /*@unchecked@*/ /*@only@*/ /*@null@*/ 00625 rpmioPool _specPool; 00626 00627 static Spec specGetPool(rpmioPool pool) 00628 { 00629 Spec spec; 00630 00631 if (_specPool == NULL) { 00632 _specPool = rpmioNewPool("spec", sizeof(*spec), -1, _spec_debug, 00633 NULL, NULL, specFini); 00634 pool = _specPool; 00635 } 00636 spec = (Spec) rpmioGetPool(pool, sizeof(*spec)); 00637 memset(((char *)spec)+sizeof(spec->_item), 0, sizeof(*spec)-sizeof(spec->_item)); 00638 return spec; 00639 } 00640 00641 Spec newSpec(void) 00642 { 00643 static const char _spec_line_buffer_size[] = 00644 "%{?_spec_line_buffer_size}%{!?_spec_line_buffer_size:100000}"; 00645 Spec spec = specGetPool(_specPool); 00646 00647 spec->specFile = NULL; 00648 00649 spec->sl = newSl(); 00650 spec->st = newSt(); 00651 00652 spec->fileStack = NULL; 00653 spec->lbuf_len = (size_t)rpmExpandNumeric(_spec_line_buffer_size); 00654 spec->lbuf = (char *)xmalloc(spec->lbuf_len); 00655 spec->lbuf[0] = '\0'; 00656 spec->line = spec->lbuf; 00657 spec->nextline = NULL; 00658 spec->nextpeekc = '\0'; 00659 spec->lineNum = 0; 00660 spec->readStack = xmalloc(sizeof(*spec->readStack)); 00661 spec->readStack->next = NULL; 00662 spec->readStack->reading = 1; 00663 00664 spec->rootURL = NULL; 00665 00666 memset(&spec->sstates, 0, sizeof(spec->sstates)); 00667 memset(&spec->smetrics, 0, sizeof(spec->smetrics)); 00668 00669 spec->prep = NULL; 00670 spec->build = NULL; 00671 spec->install = NULL; 00672 spec->check = NULL; 00673 spec->clean = NULL; 00674 spec->foo = NULL; 00675 spec->nfoo = 0; 00676 00677 spec->dig = NULL; 00678 00679 spec->sources = NULL; 00680 spec->packages = NULL; 00681 spec->noSource = 0; 00682 spec->numSources = 0; 00683 00684 spec->sourceRpmName = NULL; 00685 spec->sourcePkgId = NULL; 00686 spec->sourceHeader = headerNew(); 00687 spec->fi = NULL; 00688 00689 spec->buildSubdir = NULL; 00690 00691 spec->passPhrase = NULL; 00692 spec->timeCheck = 0; 00693 spec->cookie = NULL; 00694 00695 spec->BANames = NULL; 00696 spec->BACount = 0; 00697 spec->recursing = 0; 00698 spec->toplevel = 1; 00699 spec->BASpecs = NULL; 00700 00701 spec->force = 0; 00702 spec->anyarch = 0; 00703 00704 /*@i@*/ spec->macros = rpmGlobalMacroContext; 00705 00706 spec->_parseRCPOT = parseRCPOT; /* XXX hack around backward linkage. */ 00707 00708 return (Spec)rpmioLinkPoolItem((rpmioItem)spec, __FUNCTION__, __FILE__, __LINE__); 00709 } 00710 00711 /*@only@*/ 00712 struct OpenFileInfo * newOpenFileInfo(void) 00713 { 00714 struct OpenFileInfo *ofi; 00715 00716 ofi = xmalloc(sizeof(*ofi)); 00717 ofi->fd = NULL; 00718 ofi->fileName = NULL; 00719 ofi->lineNum = 0; 00720 ofi->readBuf[0] = '\0'; 00721 ofi->readPtr = NULL; 00722 ofi->next = NULL; 00723 00724 return ofi; 00725 } 00726 00731 static void 00732 printNewSpecfile(Spec spec) 00733 /*@globals fileSystem, internalState @*/ 00734 /*@modifies spec->sl->sl_lines[], spec->packages->header, 00735 fileSystem, internalState @*/ 00736 { 00737 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he)); 00738 Header h; 00739 speclines sl = spec->sl; 00740 spectags st = spec->st; 00741 const char * msgstr = NULL; 00742 int i, j; 00743 int xx; 00744 00745 if (sl == NULL || st == NULL) 00746 return; 00747 00748 for (i = 0; i < st->st_ntags; i++) { 00749 spectag t = st->st_t + i; 00750 const char * tn = tagName(t->t_tag); 00751 const char * errstr; 00752 char fmt[1024]; 00753 00754 fmt[0] = '\0'; 00755 if (t->t_msgid == NULL) 00756 h = spec->packages->header; 00757 else { 00758 Package pkg; 00759 char *fe; 00760 00761 strcpy(fmt, t->t_msgid); 00762 for (fe = fmt; *fe && *fe != '('; fe++) 00763 {} ; 00764 if (*fe == '(') *fe = '\0'; 00765 h = NULL; 00766 for (pkg = spec->packages; pkg != NULL; pkg = pkg->next) { 00767 h = pkg->header; 00768 he->tag = RPMTAG_NAME; 00769 xx = headerGet(h, he, 0); 00770 if (!strcmp(he->p.str, fmt)) { 00771 he->p.ptr = _free(he->p.ptr); 00772 /*@innerbreak@*/ break; 00773 } 00774 he->p.ptr = _free(he->p.ptr); 00775 } 00776 if (pkg == NULL || h == NULL) 00777 h = spec->packages->header; 00778 } 00779 00780 if (h == NULL) 00781 continue; 00782 00783 fmt[0] = '\0'; 00784 (void) stpcpy( stpcpy( stpcpy( fmt, "%{"), tn), "}"); 00785 msgstr = _free(msgstr); 00786 00787 /* XXX this should use queryHeader(), but prints out tn as well. */ 00788 msgstr = headerSprintf(h, fmt, NULL, rpmHeaderFormats, &errstr); 00789 if (msgstr == NULL) { 00790 rpmlog(RPMLOG_ERR, _("can't query %s: %s\n"), tn, errstr); 00791 return; 00792 } 00793 00794 switch(t->t_tag) { 00795 case RPMTAG_SUMMARY: 00796 case RPMTAG_GROUP: 00797 /*@-unqualifiedtrans@*/ 00798 sl->sl_lines[t->t_startx] = _free(sl->sl_lines[t->t_startx]); 00799 /*@=unqualifiedtrans@*/ 00800 if (t->t_lang && strcmp(t->t_lang, RPMBUILD_DEFAULT_LANG)) 00801 continue; 00802 { char *buf = xmalloc(strlen(tn) + sizeof(": ") + strlen(msgstr)); 00803 (void) stpcpy( stpcpy( stpcpy(buf, tn), ": "), msgstr); 00804 sl->sl_lines[t->t_startx] = buf; 00805 } 00806 /*@switchbreak@*/ break; 00807 case RPMTAG_DESCRIPTION: 00808 for (j = 1; j < t->t_nlines; j++) { 00809 if (*sl->sl_lines[t->t_startx + j] == '%') 00810 /*@innercontinue@*/ continue; 00811 /*@-unqualifiedtrans@*/ 00812 sl->sl_lines[t->t_startx + j] = 00813 _free(sl->sl_lines[t->t_startx + j]); 00814 /*@=unqualifiedtrans@*/ 00815 } 00816 if (t->t_lang && strcmp(t->t_lang, RPMBUILD_DEFAULT_LANG)) { 00817 sl->sl_lines[t->t_startx] = _free(sl->sl_lines[t->t_startx]); 00818 continue; 00819 } 00820 sl->sl_lines[t->t_startx + 1] = xstrdup(msgstr); 00821 if (t->t_nlines > 2) 00822 sl->sl_lines[t->t_startx + 2] = xstrdup("\n\n"); 00823 /*@switchbreak@*/ break; 00824 } 00825 } 00826 msgstr = _free(msgstr); 00827 00828 for (i = 0; i < sl->sl_nlines; i++) { 00829 const char * s = sl->sl_lines[i]; 00830 if (s == NULL) 00831 continue; 00832 printf("%s", s); 00833 if (strchr(s, '\n') == NULL && s[strlen(s)-1] != '\n') 00834 printf("\n"); 00835 } 00836 } 00837 00846 static int initSourceHeaderScriptlet(Header h, 00847 rpmTag progTag, rpmTag scriptTag, rpmiob iob) 00848 /*@modifies h @*/ 00849 { 00850 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he)); 00851 int xx; 00852 00853 if (progTag !=(rpmTag) 0) { 00854 static const char prog[] = "/bin/sh"; /* XXX FIXME */ 00855 he->tag = progTag; 00856 he->t = RPM_STRING_TYPE; 00857 he->p.str = prog; 00858 he->c = 1; 00859 xx = headerPut(h, he, 0); 00860 } 00861 00862 if (scriptTag != (rpmTag)0 && iob != NULL) { 00863 he->tag = scriptTag; 00864 he->t = RPM_STRING_TYPE; 00865 he->p.str = rpmiobStr(iob); 00866 he->c = 1; 00867 xx = headerPut(h, he, 0); 00868 } 00869 return 0; 00870 } 00871 00877 static int initSourceHeaderScriptlets(Spec spec) 00878 /*@modifies spec->sourceHeader @*/ 00879 { 00880 int xx; 00881 00882 if (spec->prep != NULL) 00883 xx = initSourceHeaderScriptlet(spec->sourceHeader, 00884 tagValue("Buildprepprog"), tagValue("Buildprep"), spec->prep); 00885 if (spec->build != NULL) 00886 xx = initSourceHeaderScriptlet(spec->sourceHeader, 00887 tagValue("Buildbuildprog"), tagValue("Buildbuild"), spec->build); 00888 if (spec->install != NULL) 00889 xx = initSourceHeaderScriptlet(spec->sourceHeader, 00890 tagValue("Buildinstallprog"), tagValue("Buildinstall"), spec->install); 00891 if (spec->check != NULL) 00892 xx = initSourceHeaderScriptlet(spec->sourceHeader, 00893 tagValue("Buildcheckprog"), tagValue("Buildcheck"), spec->check); 00894 if (spec->clean != NULL) 00895 xx = initSourceHeaderScriptlet(spec->sourceHeader, 00896 tagValue("Buildcleanprog"), tagValue("Buildclean"), spec->clean); 00897 00898 return 0; 00899 } 00900 00909 static int _specQuery(rpmts ts, QVA_t qva, const char *specName, 00910 /*@null@*/ const char *target) 00911 /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/ 00912 /*@modifies rpmGlobalMacroContext, fileSystem, internalState @*/ 00913 { 00914 Spec spec = NULL; 00915 Package pkg; 00916 int res = 1; /* assume error */ 00917 int anyarch = (target == NULL) ? 1 : 0; 00918 char * passPhrase = ""; 00919 int recursing = 0; 00920 char *cookie = NULL; 00921 int verify = 0; 00922 int xx; 00923 00924 /*@-mods@*/ /* FIX: make spec abstract */ 00925 if (parseSpec(ts, specName, "/", recursing, passPhrase, 00926 cookie, anyarch, 1, verify) 00927 || (spec = rpmtsSetSpec(ts, NULL)) == NULL) 00928 { 00929 rpmlog(RPMLOG_ERR, 00930 _("query of specfile %s failed, can't parse\n"), 00931 specName); 00932 goto exit; 00933 } 00934 /*@=mods@*/ 00935 00936 res = 0; 00937 if (specedit) { 00938 printNewSpecfile(spec); 00939 goto exit; 00940 } 00941 00942 switch (qva->qva_source) { 00943 case RPMQV_SPECSRPM: 00944 xx = initSourceHeader(spec, NULL); 00945 xx = initSourceHeaderScriptlets(spec); 00946 xx = qva->qva_showPackage(qva, ts, spec->sourceHeader); 00947 break; 00948 default: 00949 case RPMQV_SPECFILE: 00950 for (pkg = spec->packages; pkg != NULL; pkg = pkg->next) { 00951 /* If no target was specified, display all packages. 00952 * Packages with empty file lists are not produced. 00953 */ 00954 /* XXX DIEDIEDIE: this logic looks flawed. */ 00955 if (target == NULL || pkg->fileList != NULL) 00956 xx = qva->qva_showPackage(qva, ts, pkg->header); 00957 } 00958 break; 00959 } 00960 00961 exit: 00962 spec = freeSpec(spec); 00963 return res; 00964 } 00965 00966 int rpmspecQuery(rpmts ts, QVA_t qva, const char * arg) 00967 { 00968 int res = 1; 00969 const char * targets = rpmcliTargets; 00970 char *target; 00971 const char * t; 00972 const char * te; 00973 int nqueries = 0; 00974 00975 if (qva->qva_showPackage == NULL) 00976 goto exit; 00977 00978 if (targets == NULL) { 00979 res = _specQuery(ts, qva, arg, NULL); 00980 nqueries++; 00981 goto exit; 00982 } 00983 00984 rpmlog(RPMLOG_DEBUG, 00985 _("Query specfile for platform(s): %s\n"), targets); 00986 for (t = targets; *t != '\0'; t = te) { 00987 /* Parse out next target platform. */ 00988 if ((te = strchr(t, ',')) == NULL) 00989 te = t + strlen(t); 00990 target = alloca(te-t+1); 00991 strncpy(target, t, (te-t)); 00992 target[te-t] = '\0'; 00993 if (*te != '\0') 00994 te++; 00995 00996 /* Query spec for this target platform. */ 00997 rpmlog(RPMLOG_DEBUG, _(" target platform: %s\n"), target); 00998 /* Read in configuration for target. */ 00999 if (t != targets) { 01000 rpmFreeMacros(NULL); 01001 rpmFreeRpmrc(); 01002 (void) rpmReadConfigFiles(NULL, target); 01003 } 01004 res = _specQuery(ts, qva, arg, target); 01005 nqueries++; 01006 if (res) break; 01007 } 01008 01009 exit: 01010 /* Restore original configuration. */ 01011 if (nqueries > 1) { 01012 t = targets; 01013 if ((te = strchr(t, ',')) == NULL) 01014 te = t + strlen(t); 01015 target = alloca(te-t+1); 01016 strncpy(target, t, (te-t)); 01017 target[te-t] = '\0'; 01018 if (*te != '\0') 01019 te++; 01020 rpmFreeMacros(NULL); 01021 rpmFreeRpmrc(); 01022 (void) rpmReadConfigFiles(NULL, target); 01023 } 01024 return res; 01025 }