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