rpm 5.2.1

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

- File List
- Globals

spec.c
Go to the documentation of this file.
1
6 #include "system.h"
7
8 #include <rpmio.h>
9 #include <rpmiotypes.h>
10 #include <rpmlog.h>
11 #include "buildio.h"
12 #include "rpmds.h"
13 #include "rpmfi.h"
14 #include "rpmts.h"
15
16 #include "rpmlua.h"
17
18 #include "debug.h"
19
20 /*@-redecl@*/
21 extern int specedit;
22 /*@=redecl@*/
23
24 #define SKIPWHITE(_x) {while(*(_x) && (xisspace(*_x) || *(_x) == ',')) (_x)++;}
25 #define SKIPNONWHITE(_x){while(*(_x) &&!(xisspace(*_x) || *(_x) == ',')) (_x)++;}
26
27 /*@access rpmluav @*/
28
33 static inline
34 /*@null@*/ struct TriggerFileEntry * freeTriggerFiles(/*@only@*/ /*@null@*/ struct TriggerFileEntry * p)
35 /*@modifies p @*/
36 {
37 struct TriggerFileEntry *o, *q = p;
38
39 while (q != NULL) {
40 o = q;
41 q = q->next;
42 o->fileName = _free(o->fileName);
43 o->script = _free(o->script);
44 o->prog = _free(o->prog);
45 o = _free(o);
46 }
47 return NULL;
48 }
49
55 static inline
56 /*@null@*/ struct Source * freeSources(/*@only@*/ /*@null@*/ struct Source * s)
57 /*@modifies s @*/
58 {
59 struct Source *r, *t = s;
60
61 while (t != NULL) {
62 r = t;
63 t = t->next;
64 r->fullSource = _free(r->fullSource);
65 r = _free(r);
66 }
67 return NULL;
68 }
69
70 rpmRC lookupPackage(Spec spec, const char *name, int flag, /*@out@*/Package *pkg)
71 {
72 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
73 char *NV = NULL;
74 char *N = NULL;
75 char *V = NULL;
76 Package p, lastp;
77 int xx;
78
79 /* "main" package */
80 if (name == NULL) {
81 if (pkg)
82 *pkg = spec->packages;
83 return RPMRC_OK;
84 }
85
86 /* Construct package name */
87 if (flag == PART_SUBNAME) {
88 he->tag = RPMTAG_NAME;
89 xx = headerGet(spec->packages->header, he, 0);
90 assert(xx != 0 && he->p.str != NULL);
91 N = rpmExpand(he->p.str, "-", name, NULL);
92 he->p.ptr = _free(he->p.ptr);
93 } else {
94 N = xstrdup(name);
95 if ((V = strrchr(N, '-')) != NULL) {
96 NV = xstrdup(N);
97 *V++ = '\0';
98 }
99 }
100
101 /* Match last package with same N or same {N,V} */
102 lastp = NULL;
103 for (p = spec->packages; p != NULL; p = p->next) {
104 char *nv, *n, *v;
105 nv = n = v = NULL;
106 he->tag = RPMTAG_NAME;
107 xx = headerGet(p->header, he, 0);
108 if (xx && he->p.str != NULL) {
109 n = (char *) he->p.str;
110 he->p.str = NULL;
111 }
112 if (NV != NULL) {
113 he->tag = RPMTAG_VERSION;
114 xx = headerGet(p->header, he, 0);
115 if (xx && he->p.str != NULL) {
116 v = (char *) he->p.str;
117 he->p.str = NULL;
118 nv = rpmExpand(n, "-", v, NULL);
119 }
120 }
121
122 if (NV == NULL) {
123 if (!strcmp(N, n))
124 lastp = p;
125 } else {
126 if (!strcmp(NV, nv) || !strcmp(NV, n)
127 || (!strcmp(N, n) && (V == NULL || !strcmp(V, v))))
128 lastp = p;
129 }
130 /*@-usereleased@*/
131 n = _free(n);
132 v = _free(v);
133 nv = _free(nv);
134 /*@=usereleased@*/
135 }
136
137 if (pkg)
138 /*@-dependenttrans@*/ *pkg = lastp; /*@=dependenttrans@*/
139 NV = _free(NV);
140 N = _free(N);
141 return ((lastp == NULL) ? RPMRC_FAIL : RPMRC_OK);
142 }
143
144 Package newPackage(/*@unused@*/ Spec spec)
145 {
146 Package p;
147
148 p = xcalloc(1, sizeof(*p));
149
150 p->header = headerNew();
151 p->ds = NULL;
152
153 p->autoProv = ((_rpmbuildFlags & 0x1) != 0);
154 p->autoReq = ((_rpmbuildFlags & 0x2) != 0);
155
156 #if 0
157 p->reqProv = NULL;
158 p->triggers = NULL;
159 p->triggerScripts = NULL;
160 #endif
161
162 p->triggerFiles = NULL;
163
164 p->fileFile = NULL;
165 p->fileList = NULL;
166
167 p->cpioList = NULL;
168
169 p->preInFile = NULL;
170 p->postInFile = NULL;
171 p->preUnFile = NULL;
172 p->postUnFile = NULL;
173 p->verifyFile = NULL;
174 p->sanityCheckFile = NULL;
175
176 p->specialDoc = NULL;
177
178 p->next = NULL;
179
180 return p;
181 }
182
183 Package freePackage(Package pkg)
184 {
185 if (pkg == NULL) return NULL;
186
187 pkg->preInFile = _free(pkg->preInFile);
188 pkg->postInFile = _free(pkg->postInFile);
189 pkg->preUnFile = _free(pkg->preUnFile);
190 pkg->postUnFile = _free(pkg->postUnFile);
191 pkg->verifyFile = _free(pkg->verifyFile);
192 pkg->sanityCheckFile = _free(pkg->sanityCheckFile);
193
194 (void)headerFree(pkg->header);
195 pkg->header = NULL;
196 (void)rpmdsFree(pkg->ds);
197 pkg->ds = NULL;
198 pkg->fileList = rpmiobFree(pkg->fileList);
199 pkg->fileFile = _free(pkg->fileFile);
200 if (pkg->cpioList != NULL) {
201 rpmfi fi = pkg->cpioList;
202 pkg->cpioList = NULL;
203 fi = rpmfiFree(fi);
204 }
205
206 pkg->specialDoc = rpmiobFree(pkg->specialDoc);
207 pkg->triggerFiles = freeTriggerFiles(pkg->triggerFiles);
208
209 pkg = _free(pkg);
210 return NULL;
211 }
212
213 Package freePackages(Package packages)
214 {
215 Package p;
216
217 while ((p = packages) != NULL) {
218 packages = p->next;
219 p->next = NULL;
220 p = freePackage(p);
221 }
222 return NULL;
223 }
224
227 static inline /*@owned@*/ struct Source *findSource(Spec spec, rpmuint32_t num, int flag)
228 /*@*/
229 {
230 struct Source *p;
231
232 for (p = spec->sources; p != NULL; p = p->next)
233 if ((num == p->num) && (p->flags & flag)) return p;
234
235 return NULL;
236 }
237
240 int SpecSourceCount(Spec spec)
241 {
242 return spec->numSources;
243 }
244
247 SpecSource getSource(Spec spec, int num)
248 /* @ */
249 {
250 struct Source *p = spec->sources;
251 int i;
252
253 for (i = 0; i < num; i++)
254 if ((p = p->next) == NULL) return NULL;
255
256 /*@-usereleased@*/
257 return p;
258 /*@=usereleased@*/
259 }
260
263 const char * specSourceName(SpecSource source)
264 {
265 return source->source;
266 }
267
270 const char * specFullSourceName(SpecSource source)
271 {
272 return source->fullSource;
273 }
274
277 int specSourceNum(SpecSource source)
278 {
279 return source->num;
280 }
281
284 int specSourceFlags(SpecSource source)
285 {
286 return source->flags;
287 }
288
289 int parseNoSource(Spec spec, const char * field, rpmTag tag)
290 {
291 const char *f, *fe;
292 const char *name;
293 rpmuint32_t num, flag;
294
295 if (tag == RPMTAG_NOSOURCE) {
296 flag = RPMFILE_SOURCE;
297 name = "source";
298 } else {
299 flag = RPMFILE_PATCH;
300 name = "patch";
301 }
302
303 fe = field;
304 for (f = fe; *f != '\0'; f = fe) {
305 struct Source *p;
306
307 SKIPWHITE(f);
308 if (*f == '\0')
309 break;
310 fe = f;
311 SKIPNONWHITE(fe);
312 if (*fe != '\0') fe++;
313
314 if (parseNum(f, &num)) {
315 rpmlog(RPMLOG_ERR, _("line %d: Bad number: %s\n"),
316 spec->lineNum, f);
317 return RPMRC_FAIL;
318 }
319
320 if (! (p = findSource(spec, num, flag))) {
321 rpmlog(RPMLOG_ERR, _("line %d: Bad no%s number: %d\n"),
322 spec->lineNum, name, num);
323 return RPMRC_FAIL;
324 }
325
326 p->flags |= RPMFILE_GHOST;
327
328 }
329
330 return RPMRC_OK;
331 }
332
333 int addSource(Spec spec, /*@unused@*/ Package pkg,
334 const char *field, rpmTag tag)
335 {
336 struct Source *p;
337 #if defined(RPM_VENDOR_OPENPKG) /* regular-ordered-sources */
338 struct Source *p_last;
339 #endif
340 int flag = 0;
341 const char *name = NULL;
342 const char *mdir = NULL;
343 char *nump;
344 const char *fieldp = NULL;
345 char buf[BUFSIZ];
346 rpmuint32_t num = 0;
347
348 buf[0] = '\0';
349 switch (tag) {
350 case RPMTAG_SOURCE:
351 flag = RPMFILE_SOURCE;
352 name = "source";
353 fieldp = spec->line + (sizeof("Source")-1);
354 break;
355 case RPMTAG_PATCH:
356 flag = RPMFILE_PATCH;
357 name = "patch";
358 fieldp = spec->line + (sizeof("Patch")-1);
359 break;
360 case RPMTAG_ICON:
361 flag = RPMFILE_ICON;
362 name = "icon";
363 fieldp = NULL;
364 break;
365 default:
366 assert(0);
367 /*@notreached@*/ break;
368 }
369 #if !defined(RPM_VENDOR_OPENPKG) /* splitted-source-directory */
370 mdir = getSourceDir(flag);
371 assert(mdir != NULL);
372 #endif
373
374 /* Get the number */
375 if (fieldp != NULL) {
376 /* We already know that a ':' exists, and that there */
377 /* are no spaces before it. */
378 /* This also now allows for spaces and tabs between */
379 /* the number and the ':' */
380
381 nump = buf;
382 while ((*fieldp != ':') && (*fieldp != ' ') && (*fieldp != '\t'))
383 *nump++ = *fieldp++;
384 *nump = '\0';
385
386 nump = buf;
387 SKIPSPACE(nump);
388 if (nump == NULL || *nump == '\0')
389 num = 0;
390 else if (parseNum(buf, &num)) {
391 rpmlog(RPMLOG_ERR, _("line %d: Bad %s number: %s\n"),
392 spec->lineNum, name, spec->line);
393 return RPMRC_FAIL;
394 }
395 }
396
397 /* Check whether tags of the same number haven't already been defined */
398 for (p = spec->sources; p != NULL; p = p->next) {
399 if ( p->num != num ) continue;
400 if ((tag == RPMTAG_SOURCE && p->flags == RPMFILE_SOURCE) ||
401 (tag == RPMTAG_PATCH && p->flags == RPMFILE_PATCH)) {
402 rpmlog(RPMLOG_ERR, _("%s %d defined multiple times\n"), name, num);
403 return RPMRC_FAIL;
404 }
405 }
406
407 /* Create the entry and link it in */
408 p = xmalloc(sizeof(*p));
409 p->num = num;
410 p->fullSource = xstrdup(field);
411 p->flags = flag;
412 p->source = strrchr(p->fullSource, '/');
413 if (p->source)
414 p->source++;
415 else
416 p->source = p->fullSource;
417
418 #if defined(RPM_VENDOR_OPENPKG) /* regular-ordered-sources */
419 p->next = NULL;
420 p_last = spec->sources;
421 while (p_last != NULL && p_last->next != NULL)
422 p_last = p_last->next;
423 if (p_last != NULL)
424 p_last->next = p;
425 else
426 spec->sources = p;
427 #else
428 p->next = spec->sources;
429 spec->sources = p;
430 #endif
431
432 spec->numSources++;
433
434 /* XXX FIXME: need to add ICON* macros. */
435 #if defined(RPM_VENDOR_OPENPKG) /* splitted-source-directory */
436 mdir = getSourceDir(flag, p->source);
437 #endif
438 if (tag != RPMTAG_ICON) {
439 const char *body = rpmGenPath(NULL, mdir, p->source);
440
441 sprintf(buf, "%s%d",
442 (flag & RPMFILE_PATCH) ? "PATCH" : "SOURCE", num);
443 addMacro(spec->macros, buf, NULL, body, RMIL_SPEC);
444 sprintf(buf, "%sURL%d",
445 (flag & RPMFILE_PATCH) ? "PATCH" : "SOURCE", num);
446 addMacro(spec->macros, buf, NULL, p->fullSource, RMIL_SPEC);
447 #ifdef WITH_LUA
448 if (!spec->recursing) {
449 rpmlua lua = NULL; /* global state */
450 const char * what = (flag & RPMFILE_PATCH) ? "patches" : "sources";
451 rpmluav var = rpmluavNew();
452
453 rpmluaPushTable(lua, what);
454 rpmluavSetListMode(var, 1);
455 rpmluavSetValue(var, RPMLUAV_STRING, body);
456 rpmluaSetVar(lua, var);
457 /*@-moduncon@*/
458 var = (rpmluav) rpmluavFree(var);
459 /*@=moduncon@*/
460 rpmluaPop(lua);
461 }
462 #endif
463 body = _free(body);
464 }
465
466 return RPMRC_OK;
467 }
468
471 static inline /*@only@*/ /*@null@*/ speclines newSl(void)
472 /*@*/
473 {
474 speclines sl = NULL;
475 if (specedit) {
476 sl = xmalloc(sizeof(*sl));
477 sl->sl_lines = NULL;
478 sl->sl_nalloc = 0;
479 sl->sl_nlines = 0;
480 }
481 return sl;
482 }
483
486 static inline /*@null@*/ speclines freeSl(/*@only@*/ /*@null@*/ speclines sl)
487 /*@modifies sl @*/
488 {
489 int i;
490 if (sl == NULL) return NULL;
491 for (i = 0; i < sl->sl_nlines; i++)
492 /*@-unqualifiedtrans@*/
493 sl->sl_lines[i] = _free(sl->sl_lines[i]);
494 /*@=unqualifiedtrans@*/
495 sl->sl_lines = _free(sl->sl_lines);
496 return _free(sl);
497 }
498
501 static inline /*@only@*/ /*@null@*/ spectags newSt(void)
502 /*@*/
503 {
504 spectags st = NULL;
505 if (specedit) {
506 st = xmalloc(sizeof(*st));
507 st->st_t = NULL;
508 st->st_nalloc = 0;
509 st->st_ntags = 0;
510 }
511 return st;
512 }
513
516 static inline /*@null@*/ spectags freeSt(/*@only@*/ /*@null@*/ spectags st)
517 /*@modifies st @*/
518 {
519 int i;
520 if (st == NULL) return NULL;
521 for (i = 0; i < st->st_ntags; i++) {
522 spectag t = st->st_t + i;
523 t->t_lang = _free(t->t_lang);
524 t->t_msgid = _free(t->t_msgid);
525 }
526 st->st_t = _free(st->st_t);
527 return _free(st);
528 }
529
530 Spec newSpec(void)
531 {
532 Spec spec = xcalloc(1, sizeof(*spec));
533
534 spec->specFile = NULL;
535
536 spec->sl = newSl();
537 spec->st = newSt();
538
539 spec->fileStack = NULL;
540 spec->lbuf_len = (size_t)rpmExpandNumeric("%{?_spec_line_buffer_size}%{!?_spec_line_buffer_size:100000}");
541 spec->lbuf = (char *)xcalloc(1, spec->lbuf_len);
542 spec->line = spec->lbuf;
543 spec->nextline = NULL;
544 spec->nextpeekc = '\0';
545 spec->lineNum = 0;
546 spec->readStack = xcalloc(1, sizeof(*spec->readStack));
547 spec->readStack->next = NULL;
548 spec->readStack->reading = 1;
549
550 spec->rootURL = NULL;
551 spec->prep = NULL;
552 spec->build = NULL;
553 spec->install = NULL;
554 spec->check = NULL;
555 spec->clean = NULL;
556 spec->foo = NULL;
557 spec->nfoo = 0;
558
559 spec->sources = NULL;
560 spec->packages = NULL;
561 spec->noSource = 0;
562 spec->numSources = 0;
563
564 spec->sourceRpmName = NULL;
565 spec->sourcePkgId = NULL;
566 spec->sourceHeader = headerNew();
567 spec->sourceCpioList = NULL;
568
569 spec->buildSubdir = NULL;
570
571 spec->passPhrase = NULL;
572 spec->timeCheck = 0;
573 spec->cookie = NULL;
574
575 spec->BANames = NULL;
576 spec->BACount = 0;
577 spec->recursing = 0;
578 spec->toplevel = 1;
579 spec->BASpecs = NULL;
580
581 spec->force = 0;
582 spec->anyarch = 0;
583
584 /*@i@*/ spec->macros = rpmGlobalMacroContext;
585
586 spec->_parseRCPOT = parseRCPOT; /* XXX hack around backward linkage. */
587
588 return spec;
589 }
590
591 Spec freeSpec(Spec spec)
592 {
593 struct ReadLevelEntry *rl;
594
595 if (spec == NULL) return NULL;
596
597 spec->lbuf = _free(spec->lbuf);
598
599 spec->sl = freeSl(spec->sl);
600 spec->st = freeSt(spec->st);
601
602 spec->prep = rpmiobFree(spec->prep);
603 spec->build = rpmiobFree(spec->build);
604 spec->install = rpmiobFree(spec->install);
605 spec->check = rpmiobFree(spec->check);
606 spec->clean = rpmiobFree(spec->clean);
607 spec->foo = tagStoreFree(spec->foo, spec->nfoo);
608 spec->nfoo = 0;
609
610 spec->buildSubdir = _free(spec->buildSubdir);
611 spec->rootURL = _free(spec->rootURL);
612 spec->specFile = _free(spec->specFile);
613
614 closeSpec(spec);
615
616 while (spec->readStack) {
617 rl = spec->readStack;
618 /*@-dependenttrans@*/
619 spec->readStack = rl->next;
620 /*@=dependenttrans@*/
621 rl->next = NULL;
622 rl = _free(rl);
623 }
624
625 spec->sourceRpmName = _free(spec->sourceRpmName);
626 spec->sourcePkgId = _free(spec->sourcePkgId);
627 spec->sourceHeader = headerFree(spec->sourceHeader);
628
629 if (spec->sourceCpioList != NULL) {
630 rpmfi fi = spec->sourceCpioList;
631 spec->sourceCpioList = NULL;
632 fi = rpmfiFree(fi);
633 }
634
635 if (!spec->recursing) {
636 if (spec->BASpecs != NULL)
637 while (spec->BACount--) {
638 /*@-unqualifiedtrans@*/
639 spec->BASpecs[spec->BACount] =
640 freeSpec(spec->BASpecs[spec->BACount]);
641 /*@=unqualifiedtrans@*/
642 }
643 /*@-compdef@*/
644 spec->BASpecs = _free(spec->BASpecs);
645 /*@=compdef@*/
646 }
647 spec->BANames = _free(spec->BANames);
648
649 spec->passPhrase = _free(spec->passPhrase);
650 spec->cookie = _free(spec->cookie);
651
652 #ifdef WITH_LUA
653 { rpmlua lua = NULL; /* global state */
654 rpmluaDelVar(lua, "patches");
655 rpmluaDelVar(lua, "sources");
656 }
657 #endif
658
659 spec->sources = freeSources(spec->sources);
660 spec->packages = freePackages(spec->packages);
661
662 spec = _free(spec);
663
664 return spec;
665 }
666
667 /*@only@*/
668 struct OpenFileInfo * newOpenFileInfo(void)
669 {
670 struct OpenFileInfo *ofi;
671
672 ofi = xmalloc(sizeof(*ofi));
673 ofi->fd = NULL;
674 ofi->fileName = NULL;
675 ofi->lineNum = 0;
676 ofi->readBuf[0] = '\0';
677 ofi->readPtr = NULL;
678 ofi->next = NULL;
679
680 return ofi;
681 }
682
687 static void
688 printNewSpecfile(Spec spec)
689 /*@globals fileSystem, internalState @*/
690 /*@modifies spec->sl->sl_lines[], spec->packages->header,
691 fileSystem, internalState @*/
692 {
693 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
694 Header h;
695 speclines sl = spec->sl;
696 spectags st = spec->st;
697 const char * msgstr = NULL;
698 int i, j;
699 int xx;
700
701 if (sl == NULL || st == NULL)
702 return;
703
704 for (i = 0; i < st->st_ntags; i++) {
705 spectag t = st->st_t + i;
706 const char * tn = tagName(t->t_tag);
707 const char * errstr;
708 char fmt[1024];
709
710 fmt[0] = '\0';
711 if (t->t_msgid == NULL)
712 h = spec->packages->header;
713 else {
714 Package pkg;
715 char *fe;
716
717 strcpy(fmt, t->t_msgid);
718 for (fe = fmt; *fe && *fe != '('; fe++)
719 {} ;
720 if (*fe == '(') *fe = '\0';
721 h = NULL;
722 for (pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
723 h = pkg->header;
724 he->tag = RPMTAG_NAME;
725 xx = headerGet(h, he, 0);
726 if (!strcmp(he->p.str, fmt)) {
727 he->p.ptr = _free(he->p.ptr);
728 /*@innerbreak@*/ break;
729 }
730 he->p.ptr = _free(he->p.ptr);
731 }
732 if (pkg == NULL || h == NULL)
733 h = spec->packages->header;
734 }
735
736 if (h == NULL)
737 continue;
738
739 fmt[0] = '\0';
740 (void) stpcpy( stpcpy( stpcpy( fmt, "%{"), tn), "}");
741 msgstr = _free(msgstr);
742
743 /* XXX this should use queryHeader(), but prints out tn as well. */
744 msgstr = headerSprintf(h, fmt, NULL, rpmHeaderFormats, &errstr);
745 if (msgstr == NULL) {
746 rpmlog(RPMLOG_ERR, _("can't query %s: %s\n"), tn, errstr);
747 return;
748 }
749
750 switch(t->t_tag) {
751 case RPMTAG_SUMMARY:
752 case RPMTAG_GROUP:
753 /*@-unqualifiedtrans@*/
754 sl->sl_lines[t->t_startx] = _free(sl->sl_lines[t->t_startx]);
755 /*@=unqualifiedtrans@*/
756 if (t->t_lang && strcmp(t->t_lang, RPMBUILD_DEFAULT_LANG))
757 continue;
758 { char *buf = xmalloc(strlen(tn) + sizeof(": ") + strlen(msgstr));
759 (void) stpcpy( stpcpy( stpcpy(buf, tn), ": "), msgstr);
760 sl->sl_lines[t->t_startx] = buf;
761 }
762 /*@switchbreak@*/ break;
763 case RPMTAG_DESCRIPTION:
764 for (j = 1; j < t->t_nlines; j++) {
765 if (*sl->sl_lines[t->t_startx + j] == '%')
766 /*@innercontinue@*/ continue;
767 /*@-unqualifiedtrans@*/
768 sl->sl_lines[t->t_startx + j] =
769 _free(sl->sl_lines[t->t_startx + j]);
770 /*@=unqualifiedtrans@*/
771 }
772 if (t->t_lang && strcmp(t->t_lang, RPMBUILD_DEFAULT_LANG)) {
773 sl->sl_lines[t->t_startx] = _free(sl->sl_lines[t->t_startx]);
774 continue;
775 }
776 sl->sl_lines[t->t_startx + 1] = xstrdup(msgstr);
777 if (t->t_nlines > 2)
778 sl->sl_lines[t->t_startx + 2] = xstrdup("\n\n");
779 /*@switchbreak@*/ break;
780 }
781 }
782 msgstr = _free(msgstr);
783
784 for (i = 0; i < sl->sl_nlines; i++) {
785 const char * s = sl->sl_lines[i];
786 if (s == NULL)
787 continue;
788 printf("%s", s);
789 if (strchr(s, '\n') == NULL && s[strlen(s)-1] != '\n')
790 printf("\n");
791 }
792 }
793
802 static int initSourceHeaderScriptlet(Header h,
803 rpmTag progTag, rpmTag scriptTag, rpmiob iob)
804 /*@modifies h @*/
805 {
806 HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
807 int xx;
808
809 if (progTag !=(rpmTag) 0) {
810 static const char prog[] = "/bin/sh"; /* XXX FIXME */
811 he->tag = progTag;
812 he->t = RPM_STRING_TYPE;
813 he->p.str = prog;
814 he->c = 1;
815 xx = headerPut(h, he, 0);
816 }
817
818 if (scriptTag != (rpmTag)0 && iob != NULL) {
819 he->tag = scriptTag;
820 he->t = RPM_STRING_TYPE;
821 he->p.str = rpmiobStr(iob);
822 he->c = 1;
823 xx = headerPut(h, he, 0);
824 }
825 return 0;
826 }
827
833 static int initSourceHeaderScriptlets(Spec spec)
834 /*@modifies spec->sourceHeader @*/
835 {
836 int xx;
837
838 if (spec->prep != NULL)
839 xx = initSourceHeaderScriptlet(spec->sourceHeader,
840 tagValue("Buildprepprog"), tagValue("Buildprep"), spec->prep);
841 if (spec->build != NULL)
842 xx = initSourceHeaderScriptlet(spec->sourceHeader,
843 tagValue("Buildbuildprog"), tagValue("Buildbuild"), spec->build);
844 if (spec->install != NULL)
845 xx = initSourceHeaderScriptlet(spec->sourceHeader,
846 tagValue("Buildinstallprog"), tagValue("Buildinstall"), spec->install);
847 if (spec->check != NULL)
848 xx = initSourceHeaderScriptlet(spec->sourceHeader,
849 tagValue("Buildcheckprog"), tagValue("Buildcheck"), spec->check);
850 if (spec->clean != NULL)
851 xx = initSourceHeaderScriptlet(spec->sourceHeader,
852 tagValue("Buildcleanprog"), tagValue("Buildclean"), spec->clean);
853
854 return 0;
855 }
856
865 static int _specQuery(rpmts ts, QVA_t qva, const char *specName,
866 /*@null@*/ const char *target)
867 /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
868 /*@modifies rpmGlobalMacroContext, fileSystem, internalState @*/
869 {
870 Spec spec = NULL;
871 Package pkg;
872 int res = 1; /* assume error */
873 int anyarch = (target == NULL) ? 1 : 0;
874 char * passPhrase = "";
875 int recursing = 0;
876 char *cookie = NULL;
877 int verify = 0;
878 int xx;
879
880 /*@-mods@*/ /* FIX: make spec abstract */
881 if (parseSpec(ts, specName, "/", recursing, passPhrase,
882 cookie, anyarch, 1, verify)
883 || (spec = rpmtsSetSpec(ts, NULL)) == NULL)
884 {
885 rpmlog(RPMLOG_ERR,
886 _("query of specfile %s failed, can't parse\n"),
887 specName);
888 goto exit;
889 }
890 /*@=mods@*/
891
892 res = 0;
893 if (specedit) {
894 printNewSpecfile(spec);
895 goto exit;
896 }
897
898 switch (qva->qva_source) {
899 case RPMQV_SPECSRPM:
900 xx = initSourceHeader(spec, NULL);
901 xx = initSourceHeaderScriptlets(spec);
902 xx = qva->qva_showPackage(qva, ts, spec->sourceHeader);
903 break;
904 default:
905 case RPMQV_SPECFILE:
906 for (pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
907 /* If no target was specified, display all packages.
908 * Packages with empty file lists are not produced.
909 */
910 /* XXX DIEDIEDIE: this logic looks flawed. */
911 if (target == NULL || pkg->fileList != NULL)
912 xx = qva->qva_showPackage(qva, ts, pkg->header);
913 }
914 break;
915 }
916
917 exit:
918 spec = freeSpec(spec);
919 return res;
920 }
921
922 int rpmspecQuery(rpmts ts, QVA_t qva, const char * arg)
923 {
924 int res = 1;
925 const char * targets = rpmcliTargets;
926 char *target;
927 const char * t;
928 const char * te;
929 int nqueries = 0;
930
931 if (qva->qva_showPackage == NULL)
932 goto exit;
933
934 if (targets == NULL) {
935 res = _specQuery(ts, qva, arg, NULL);
936 nqueries++;
937 goto exit;
938 }
939
940 rpmlog(RPMLOG_DEBUG,
941 _("Query specfile for platform(s): %s\n"), targets);
942 for (t = targets; *t != '\0'; t = te) {
943 /* Parse out next target platform. */
944 if ((te = strchr(t, ',')) == NULL)
945 te = t + strlen(t);
946 target = alloca(te-t+1);
947 strncpy(target, t, (te-t));
948 target[te-t] = '\0';
949 if (*te != '\0')
950 te++;
951
952 /* Query spec for this target platform. */
953 rpmlog(RPMLOG_DEBUG, _(" target platform: %s\n"), target);
954 /* Read in configuration for target. */
955 if (t != targets) {
956 rpmFreeMacros(NULL);
957 rpmFreeRpmrc();
958 (void) rpmReadConfigFiles(NULL, target);
959 }
960 res = _specQuery(ts, qva, arg, target);
961 nqueries++;
962 if (res) break;
963 }
964
965 exit:
966 /* Restore original configuration. */
967 if (nqueries > 1) {
968 t = targets;
969 if ((te = strchr(t, ',')) == NULL)
970 te = t + strlen(t);
971 target = alloca(te-t+1);
972 strncpy(target, t, (te-t));
973 target[te-t] = '\0';
974 if (*te != '\0')
975 te++;
976 rpmFreeMacros(NULL);
977 rpmFreeRpmrc();
978 (void) rpmReadConfigFiles(NULL, target);
979 }
980 return res;
981 }