rpm  5.2.1
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 
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);
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);
208 
209  pkg = _free(pkg);
210  return NULL;
211 }
212 
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 
241 {
242  return spec->numSources;
243 }
244 
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 
264 {
265  return source->source;
266 }
267 
271 {
272  return source->fullSource;
273 }
274 
278 {
279  return source->num;
280 }
281 
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 
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 
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@*/
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
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 
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 
834  /*@modifies spec->sourceHeader @*/
835 {
836  int xx;
837 
838  if (spec->prep != NULL)
840  tagValue("Buildprepprog"), tagValue("Buildprep"), spec->prep);
841  if (spec->build != NULL)
843  tagValue("Buildbuildprog"), tagValue("Buildbuild"), spec->build);
844  if (spec->install != NULL)
846  tagValue("Buildinstallprog"), tagValue("Buildinstall"), spec->install);
847  if (spec->check != NULL)
849  tagValue("Buildcheckprog"), tagValue("Buildcheck"), spec->check);
850  if (spec->clean != NULL)
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  {
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 
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 }