rpm  5.4.10
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 <rpmpgp.h>
12 
13 #include "buildio.h"
14 #include "rpmds.h"
15 #include "rpmfi.h"
16 #include "rpmts.h"
17 
18 #include "rpmlua.h"
19 
20 #include "debug.h"
21 
22 /*@unchecked@*/
24 
25 /*@unchecked@*/
27 
28 /*@-redecl@*/
29 extern int specedit;
30 
31 /*@-redecl@*/
32 extern int printspec;
33 
34 /*@=redecl@*/
35 
36 #define SKIPWHITE(_x) {while(*(_x) && (xisspace(*_x) || *(_x) == ',')) (_x)++;}
37 #define SKIPNONWHITE(_x){while(*(_x) &&!(xisspace(*_x) || *(_x) == ',')) (_x)++;}
38 
39 /*@access rpmluav @*/
40 
45 static inline
46 /*@null@*/ struct TriggerFileEntry * freeTriggerFiles(/*@only@*/ /*@null@*/ struct TriggerFileEntry * p)
47  /*@modifies p @*/
48 {
49  struct TriggerFileEntry *o, *q = p;
50 
51  while (q != NULL) {
52  o = q;
53  q = q->next;
54  o->fileName = _free(o->fileName);
55  o->script = _free(o->script);
56  o->prog = _free(o->prog);
57  o = _free(o);
58  }
59  return NULL;
60 }
61 
67 static inline
68 /*@null@*/ struct Source * freeSources(/*@only@*/ /*@null@*/ struct Source * s)
69  /*@modifies s @*/
70 {
71  struct Source *r, *t = s;
72 
73  while (t != NULL) {
74  r = t;
75  t = t->next;
76  r->fullSource = _free(r->fullSource);
77  r = _free(r);
78  }
79  return NULL;
80 }
81 
82 rpmRC lookupPackage(Spec spec, const char *name, int flag, /*@out@*/Package *pkgp)
83 {
84  HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he));
85  char *NV = NULL;
86  char *N = NULL;
87  char *V = NULL;
88  Package p;
89  Package lastp = spec->packages;
90  rpmRC rc = RPMRC_OK;
91  int xx;
92 
93  if (lastp == NULL) /* XXX segfault avoidance */
94  goto exit;
95  /* "main" package */
96  if (name == NULL)
97  goto exit;
98 
99  /* Construct package name */
100  if (flag == PART_SUBNAME) {
101  he->tag = RPMTAG_NAME;
102  xx = headerGet(spec->packages->header, he, 0);
103 assert(xx != 0 && he->p.str != NULL);
104  N = rpmExpand(he->p.str, "-", name, NULL);
105  he->p.ptr = _free(he->p.ptr);
106  } else {
107  N = xstrdup(name);
108  /* XXX restrict V to leading digit to prevent NV split ambiguity. */
109  if ((V = strrchr(N, '-')) != NULL && xisdigit(V[1])) {
110  NV = xstrdup(N);
111  *V++ = '\0';
112  } else
113  V = NULL;
114  }
115 
116  /* Match last package with same N or same {N,V} */
117  lastp = NULL;
118  for (p = spec->packages; p != NULL; p = p->next) {
119  char *nv, *n, *v;
120  nv = n = v = NULL;
121  he->tag = RPMTAG_NAME;
122  xx = headerGet(p->header, he, 0);
123  if (xx && he->p.str != NULL) {
124  n = (char *) he->p.str;
125  he->p.str = NULL;
126  }
127  if (NV != NULL) {
128  he->tag = RPMTAG_VERSION;
129  xx = headerGet(p->header, he, 0);
130  if (xx && he->p.str != NULL) {
131  v = (char *) he->p.str;
132  he->p.str = NULL;
133  nv = rpmExpand(n, "-", v, NULL);
134  }
135  }
136 
137  if (NV == NULL) {
138  if (!strcmp(N, n))
139  lastp = p;
140  } else {
141  if (!strcmp(NV, nv) || !strcmp(NV, n)
142  || (!strcmp(N, n) && (V == NULL || !strcmp(V, v))))
143  lastp = p;
144  }
145 /*@-usereleased@*/
146  n = _free(n);
147  v = _free(v);
148  nv = _free(nv);
149 /*@=usereleased@*/
150  }
151  rc = (lastp == NULL ? RPMRC_FAIL : RPMRC_OK);
152  NV = _free(NV);
153  N = _free(N);
154 
155 exit:
156  if (pkgp)
157  /*@-dependenttrans@*/ *pkgp = lastp; /*@=dependenttrans@*/
158  return rc;
159 }
160 
161 static void pkgFini(void * _pkg)
162  /*@modifies _pkg @*/
163 {
164  Package pkg = _pkg;
165 
166  if (pkg == NULL) return; /* XXX assert? */
167 
168  pkg->preInFile = _free(pkg->preInFile);
169  pkg->postInFile = _free(pkg->postInFile);
170  pkg->preUnFile = _free(pkg->preUnFile);
171  pkg->postUnFile = _free(pkg->postUnFile);
172  pkg->verifyFile = _free(pkg->verifyFile);
174 
175  (void)headerFree(pkg->header);
176  pkg->header = NULL;
177  (void)rpmdsFree(pkg->ds);
178  pkg->ds = NULL;
179  pkg->fileList = rpmiobFree(pkg->fileList);
180  pkg->fileFile = _free(pkg->fileFile);
181  if (pkg->fi != NULL) {
182  rpmfi fi = pkg->fi;
183  pkg->fi = NULL;
184  fi = rpmfiFree(fi);
185  }
186 
187  pkg->specialDoc = rpmiobFree(pkg->specialDoc);
189 }
190 
191 /*@unchecked@*/ /*@only@*/ /*@null@*/
193 
195 {
196  Package pkg;
197 
198  if (_pkgPool == NULL) {
199  _pkgPool = rpmioNewPool("pkg", sizeof(*pkg), -1, _pkg_debug,
200  NULL, NULL, pkgFini);
201  pool = _pkgPool;
202  }
203  pkg = (Package) rpmioGetPool(pool, sizeof(*pkg));
204  memset(((char *)pkg)+sizeof(pkg->_item), 0, sizeof(*pkg)-sizeof(pkg->_item));
205  return pkg;
206 }
207 
208 Package newPackage(/*@unused@*/ Spec spec)
209 {
210  Package pkg = pkgGetPool(_pkgPool);
211 
212  pkg->header = headerNew();
213  pkg->ds = NULL;
214 
215  pkg->autoProv = ((_rpmbuildFlags & 0x1) != 0);
216  pkg->autoReq = ((_rpmbuildFlags & 0x2) != 0);
217 
218 #if 0
219  pkg->reqProv = NULL;
220  pkg->triggers = NULL;
221  pkg->triggerScripts = NULL;
222 #endif
223 
224  pkg->triggerFiles = NULL;
225 
226  pkg->fileFile = NULL;
227  pkg->fileList = NULL;
228 
229  pkg->fi = NULL;
230 
231  pkg->preInFile = NULL;
232  pkg->postInFile = NULL;
233  pkg->preUnFile = NULL;
234  pkg->postUnFile = NULL;
235  pkg->verifyFile = NULL;
236  pkg->sanityCheckFile = NULL;
237 
238  pkg->specialDoc = NULL;
239 
240  pkg->next = NULL;
241 
242  return (Package)rpmioLinkPoolItem((rpmioItem)pkg, __FUNCTION__, __FILE__, __LINE__);
243 }
244 
246 {
247  Package p;
248 
249  while ((p = packages) != NULL) {
250  packages = p->next;
251  p->next = NULL;
252  p = freePackage(p);
253  }
254  return NULL;
255 }
256 
259 static inline /*@owned@*/ struct Source *findSource(Spec spec, rpmuint32_t num, int flag)
260  /*@*/
261 {
262  struct Source *p;
263 
264  for (p = spec->sources; p != NULL; p = p->next)
265  if ((num == p->num) && (p->flags & flag)) return p;
266 
267  return NULL;
268 }
269 
273 {
274  return spec->numSources;
275 }
276 
280  /* @ */
281 {
282  struct Source *p = spec->sources;
283  int i;
284 
285  for (i = 0; i < num; i++)
286  if ((p = p->next) == NULL) return NULL;
287 
288 /*@-usereleased@*/
289  return p;
290 /*@=usereleased@*/
291 }
292 
296 {
297  return source->source;
298 }
299 
303 {
304  return source->fullSource;
305 }
306 
310 {
311  return source->num;
312 }
313 
317 {
318  return source->flags;
319 }
320 
321 int parseNoSource(Spec spec, const char * field, rpmTag tag)
322 {
323  const char *f, *fe;
324  const char *name;
325  rpmuint32_t num, flag;
326 
327  if (tag == RPMTAG_NOSOURCE) {
328  flag = RPMFILE_SOURCE;
329  name = "source";
330  } else {
331  flag = RPMFILE_PATCH;
332  name = "patch";
333  }
334 
335  fe = field;
336  for (f = fe; *f != '\0'; f = fe) {
337  struct Source *p;
338 
339  SKIPWHITE(f);
340  if (*f == '\0')
341  break;
342  fe = f;
343  SKIPNONWHITE(fe);
344  if (*fe != '\0') fe++;
345 
346  if (parseNum(f, &num)) {
347  rpmlog(RPMLOG_ERR, _("line %d: Bad number: %s\n"),
348  spec->lineNum, f);
349  return RPMRC_FAIL;
350  }
351 
352  if (! (p = findSource(spec, num, flag))) {
353  rpmlog(RPMLOG_ERR, _("line %d: Bad no%s number: %d\n"),
354  spec->lineNum, name, num);
355  return RPMRC_FAIL;
356  }
357 
358  p->flags |= RPMFILE_GHOST;
359 
360  }
361 
362  return RPMRC_OK;
363 }
364 
365 int addSource(Spec spec, /*@unused@*/ Package pkg,
366  const char *field, rpmTag tag)
367 {
368  struct Source *p;
369 #if defined(RPM_VENDOR_OPENPKG) /* regular-ordered-sources */
370  struct Source *p_last;
371 #endif
372  int flag = 0;
373  const char *name = NULL;
374  const char *mdir = NULL;
375  const char *fieldp = NULL;
376  char buf[BUFSIZ];
377  uint32_t num = 0;
378 
379  buf[0] = '\0';
380  switch (tag) {
381  case RPMTAG_SOURCE:
382  flag = RPMFILE_SOURCE;
383  name = "source";
384  fieldp = spec->line + strlen(name);
385  break;
386  case RPMTAG_PATCH:
387  flag = RPMFILE_PATCH;
388  name = "patch";
389  fieldp = spec->line + strlen(name);
390  break;
391  case RPMTAG_ICON:
392  flag = RPMFILE_ICON;
393  name = "icon";
394  fieldp = NULL;
395  break;
396  default:
397 assert(0);
398  /*@notreached@*/ break;
399  }
400 #if !defined(RPM_VENDOR_OPENPKG) /* splitted-source-directory */
401  mdir = getSourceDir(flag);
402 assert(mdir != NULL);
403 #endif
404 
405  /* Get the number */
406  if (fieldp != NULL) {
407  char * end = NULL;
408 
409  num = strtoul(fieldp, &end, 10);
410  SKIPSPACE(end);
411  if (*end != ':') {
412  rpmlog(RPMLOG_ERR, _("line %d: No ':' terminator: %s\n"),
413  spec->lineNum, spec->line);
414  return RPMRC_FAIL;
415  }
416  }
417 
418  /* Check whether tags of the same number haven't already been defined */
419  for (p = spec->sources; p != NULL; p = p->next) {
420  if ( p->num != num ) continue;
421  if ((tag == RPMTAG_SOURCE && p->flags == RPMFILE_SOURCE) ||
422  (tag == RPMTAG_PATCH && p->flags == RPMFILE_PATCH)) {
423  rpmlog(RPMLOG_ERR, _("%s %d defined multiple times\n"), name, num);
424  return RPMRC_FAIL;
425  }
426  }
427 
428  /* Create the entry and link it in */
429  p = xmalloc(sizeof(*p));
430  p->num = num;
431  p->fullSource = xstrdup(field);
432  p->flags = flag;
433  p->source = strrchr(p->fullSource, '/');
434  if (p->source)
435  p->source++;
436  else
437  p->source = p->fullSource;
438 
439 #if defined(RPM_VENDOR_OPENPKG) /* regular-ordered-sources */
440  p->next = NULL;
441  p_last = spec->sources;
442  while (p_last != NULL && p_last->next != NULL)
443  p_last = p_last->next;
444  if (p_last != NULL)
445  p_last->next = p;
446  else
447  spec->sources = p;
448 #else
449  p->next = spec->sources;
450  spec->sources = p;
451 #endif
452 
453  spec->numSources++;
454 
455  /* XXX FIXME: need to add ICON* macros. */
456 #if defined(RPM_VENDOR_OPENPKG) /* splitted-source-directory */
457  mdir = getSourceDir(flag, p->source);
458 #endif
459  if (tag != RPMTAG_ICON) {
460  const char *body = rpmGenPath(NULL, mdir, p->source);
461 
462  sprintf(buf, "%s%d",
463  (flag & RPMFILE_PATCH) ? "PATCH" : "SOURCE", num);
464  addMacro(spec->macros, buf, NULL, body, RMIL_SPEC);
465  sprintf(buf, "%sURL%d",
466  (flag & RPMFILE_PATCH) ? "PATCH" : "SOURCE", num);
467  addMacro(spec->macros, buf, NULL, p->fullSource, RMIL_SPEC);
468 #ifdef WITH_LUA
469  if (!spec->recursing) {
470  rpmlua lua = NULL; /* global state */
471  const char * what = (flag & RPMFILE_PATCH) ? "patches" : "sources";
472  rpmluav var = rpmluavNew();
473 
474  rpmluaPushTable(lua, what);
475  rpmluavSetListMode(var, 1);
476  rpmluavSetValue(var, RPMLUAV_STRING, body);
477  rpmluaSetVar(lua, var);
478 /*@-moduncon@*/
479  var = (rpmluav) rpmluavFree(var);
480 /*@=moduncon@*/
481  rpmluaPop(lua);
482  }
483 #endif
484  body = _free(body);
485  }
486 
487  return RPMRC_OK;
488 }
489 
492 static inline /*@only@*/ /*@null@*/ speclines newSl(void)
493  /*@*/
494 {
495  speclines sl = NULL;
496  if (specedit || printspec) {
497  sl = xmalloc(sizeof(*sl));
498  sl->sl_lines = NULL;
499  sl->sl_nalloc = 0;
500  sl->sl_nlines = 0;
501  }
502  return sl;
503 }
504 
507 static inline /*@null@*/ speclines freeSl(/*@only@*/ /*@null@*/ speclines sl)
508  /*@modifies sl @*/
509 {
510  int i;
511  if (sl == NULL) return NULL;
512  for (i = 0; i < sl->sl_nlines; i++)
513  /*@-unqualifiedtrans@*/
514  sl->sl_lines[i] = _free(sl->sl_lines[i]);
515  /*@=unqualifiedtrans@*/
516  sl->sl_lines = _free(sl->sl_lines);
517  return _free(sl);
518 }
519 
522 static inline /*@only@*/ /*@null@*/ spectags newSt(void)
523  /*@*/
524 {
525  spectags st = NULL;
526  if (specedit) {
527  st = xmalloc(sizeof(*st));
528  st->st_t = NULL;
529  st->st_nalloc = 0;
530  st->st_ntags = 0;
531  }
532  return st;
533 }
534 
537 static inline /*@null@*/ spectags freeSt(/*@only@*/ /*@null@*/ spectags st)
538  /*@modifies st @*/
539 {
540  int i;
541  if (st == NULL) return NULL;
542  for (i = 0; i < st->st_ntags; i++) {
543  spectag t = st->st_t + i;
544  t->t_lang = _free(t->t_lang);
545  t->t_msgid = _free(t->t_msgid);
546  }
547  st->st_t = _free(st->st_t);
548  return _free(st);
549 }
550 
551 static void specFini(void * _spec)
552  /*@modifies _spec @*/
553 {
554  Spec spec = _spec;
555  struct ReadLevelEntry *rl;
556 
557  if (spec == NULL) return; /* XXX assert? */
558 
559  spec->lbuf = _free(spec->lbuf);
560 
561  spec->sl = freeSl(spec->sl);
562  spec->st = freeSt(spec->st);
563 
564  spec->prep = rpmiobFree(spec->prep);
565  spec->build = rpmiobFree(spec->build);
566  spec->install = rpmiobFree(spec->install);
567  spec->check = rpmiobFree(spec->check);
568  spec->clean = rpmiobFree(spec->clean);
569  spec->foo = tagStoreFree(spec->foo, spec->nfoo);
570  spec->nfoo = 0;
571 
572  spec->buildSubdir = _free(spec->buildSubdir);
573  spec->rootURL = _free(spec->rootURL);
574  spec->specFile = _free(spec->specFile);
575 
576  closeSpec(spec);
577 
578  while (spec->readStack) {
579  rl = spec->readStack;
580  /*@-dependenttrans@*/
581  spec->readStack = rl->next;
582  /*@=dependenttrans@*/
583  rl->next = NULL;
584  rl = _free(rl);
585  }
586 
587  spec->sourceRpmName = _free(spec->sourceRpmName);
588  spec->sourcePkgId = _free(spec->sourcePkgId);
589  spec->sourceHeader = headerFree(spec->sourceHeader);
590 
591  if (spec->fi != NULL) {
592  rpmfi fi = spec->fi;
593  spec->fi = NULL;
594  fi = rpmfiFree(fi);
595  }
596 
597  if (!spec->recursing) {
598  if (spec->BASpecs != NULL)
599  while (spec->BACount--) {
600  /*@-unqualifiedtrans@*/
601  spec->BASpecs[spec->BACount] =
602  freeSpec(spec->BASpecs[spec->BACount]);
603  /*@=unqualifiedtrans@*/
604  }
605  /*@-compdef@*/
606  spec->BASpecs = _free(spec->BASpecs);
607  /*@=compdef@*/
608  }
609  spec->BANames = _free(spec->BANames);
610 
611  spec->passPhrase = _free(spec->passPhrase);
612  spec->cookie = _free(spec->cookie);
613 
614 #ifdef WITH_LUA
615  { rpmlua lua = NULL; /* global state */
616  rpmluaDelVar(lua, "patches");
617  rpmluaDelVar(lua, "sources");
618  }
619 #endif
620 
621  spec->sources = freeSources(spec->sources);
622 
623  spec->dig = pgpDigFree(spec->dig);
624  spec->packages = freePackages(spec->packages);
625 
626 }
627 
628 /*@unchecked@*/ /*@only@*/ /*@null@*/
630 
632 {
633  Spec spec;
634 
635  if (_specPool == NULL) {
636  _specPool = rpmioNewPool("spec", sizeof(*spec), -1, _spec_debug,
637  NULL, NULL, specFini);
638  pool = _specPool;
639  }
640  spec = (Spec) rpmioGetPool(pool, sizeof(*spec));
641  memset(((char *)spec)+sizeof(spec->_item), 0, sizeof(*spec)-sizeof(spec->_item));
642  return spec;
643 }
644 
646 {
647  static const char _spec_line_buffer_size[] =
648  "%{?_spec_line_buffer_size}%{!?_spec_line_buffer_size:100000}";
649  Spec spec = specGetPool(_specPool);
650 
651  spec->specFile = NULL;
652 
653  spec->sl = newSl();
654  spec->st = newSt();
655 
656  spec->fileStack = NULL;
657  spec->lbuf_len = (size_t)rpmExpandNumeric(_spec_line_buffer_size);
658  spec->lbuf = (char *)xmalloc(spec->lbuf_len);
659  spec->lbuf[0] = '\0';
660  spec->line = spec->lbuf;
661  spec->nextline = NULL;
662  spec->nextpeekc = '\0';
663  spec->lineNum = 0;
664  spec->readStack = xmalloc(sizeof(*spec->readStack));
665  spec->readStack->next = NULL;
666  spec->readStack->reading = 1;
667 
668  spec->rootURL = NULL;
669 
670  memset(&spec->sstates, 0, sizeof(spec->sstates));
671  memset(&spec->smetrics, 0, sizeof(spec->smetrics));
672 
673  spec->prep = NULL;
674  spec->build = NULL;
675  spec->install = NULL;
676  spec->check = NULL;
677  spec->clean = NULL;
678  spec->foo = NULL;
679  spec->nfoo = 0;
680 
681  spec->dig = NULL;
682 
683  spec->sources = NULL;
684  spec->packages = NULL;
685  spec->noSource = 0;
686  spec->numSources = 0;
687 
688  spec->sourceRpmName = NULL;
689  spec->sourcePkgId = NULL;
690  spec->sourceHeader = headerNew();
691  spec->fi = NULL;
692 
693  spec->buildSubdir = NULL;
694 
695  spec->passPhrase = NULL;
696  spec->timeCheck = 0;
697  spec->cookie = NULL;
698 
699  spec->BANames = NULL;
700  spec->BACount = 0;
701  spec->recursing = 0;
702  spec->toplevel = 1;
703  spec->BASpecs = NULL;
704 
705  spec->force = 0;
706  spec->anyarch = 0;
707 
708 /*@i@*/ spec->macros = rpmGlobalMacroContext;
709 
710  spec->_parseRCPOT = parseRCPOT; /* XXX hack around backward linkage. */
711 
712  return (Spec)rpmioLinkPoolItem((rpmioItem)spec, __FUNCTION__, __FILE__, __LINE__);
713 }
714 
715 /*@only@*/
717 {
718  struct OpenFileInfo *ofi;
719 
720  ofi = xmalloc(sizeof(*ofi));
721  ofi->fd = NULL;
722  ofi->fileName = NULL;
723  ofi->lineNum = 0;
724  ofi->readBuf[0] = '\0';
725  ofi->readPtr = NULL;
726  ofi->next = NULL;
727 
728  return ofi;
729 }
730 
735 static void
737  /*@globals fileSystem, internalState @*/
738  /*@modifies spec->sl->sl_lines[], spec->packages->header,
739  fileSystem, internalState @*/
740 {
741  HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he));
742  Header h;
743  speclines sl = spec->sl;
744  spectags st = spec->st;
745  const char * msgstr = NULL;
746  int i, j;
747  int xx;
748 
749  if (sl == NULL || st == NULL)
750  return;
751 
752  for (i = 0; i < st->st_ntags; i++) {
753  spectag t = st->st_t + i;
754  const char * tn = tagName(t->t_tag);
755  const char * errstr;
756  char fmt[1024];
757 
758  fmt[0] = '\0';
759  if (t->t_msgid == NULL)
760  h = spec->packages->header;
761  else {
762  Package pkg;
763  char *fe;
764 
765  strcpy(fmt, t->t_msgid);
766  for (fe = fmt; *fe && *fe != '('; fe++)
767  {} ;
768  if (*fe == '(') *fe = '\0';
769  h = NULL;
770  for (pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
771  h = pkg->header;
772  he->tag = RPMTAG_NAME;
773  xx = headerGet(h, he, 0);
774  if (!strcmp(he->p.str, fmt)) {
775  he->p.ptr = _free(he->p.ptr);
776  /*@innerbreak@*/ break;
777  }
778  he->p.ptr = _free(he->p.ptr);
779  }
780  if (pkg == NULL || h == NULL)
781  h = spec->packages->header;
782  }
783 
784  if (h == NULL)
785  continue;
786 
787  fmt[0] = '\0';
788  (void) stpcpy( stpcpy( stpcpy( fmt, "%{"), tn), "}");
789  msgstr = _free(msgstr);
790 
791  /* XXX this should use queryHeader(), but prints out tn as well. */
792  msgstr = headerSprintf(h, fmt, NULL, rpmHeaderFormats, &errstr);
793  if (msgstr == NULL) {
794  rpmlog(RPMLOG_ERR, _("can't query %s: %s\n"), tn, errstr);
795  return;
796  }
797 
798  switch(t->t_tag) {
799  case RPMTAG_SUMMARY:
800  case RPMTAG_GROUP:
801  /*@-unqualifiedtrans@*/
802  sl->sl_lines[t->t_startx] = _free(sl->sl_lines[t->t_startx]);
803  /*@=unqualifiedtrans@*/
804  if (t->t_lang && strcmp(t->t_lang, RPMBUILD_DEFAULT_LANG))
805  continue;
806  { char *buf = xmalloc(strlen(tn) + sizeof(": ") + strlen(msgstr));
807  (void) stpcpy( stpcpy( stpcpy(buf, tn), ": "), msgstr);
808  sl->sl_lines[t->t_startx] = buf;
809  }
810  /*@switchbreak@*/ break;
811  case RPMTAG_DESCRIPTION:
812  for (j = 1; j < t->t_nlines; j++) {
813  if (*sl->sl_lines[t->t_startx + j] == '%')
814  /*@innercontinue@*/ continue;
815  /*@-unqualifiedtrans@*/
816  sl->sl_lines[t->t_startx + j] =
817  _free(sl->sl_lines[t->t_startx + j]);
818  /*@=unqualifiedtrans@*/
819  }
820  if (t->t_lang && strcmp(t->t_lang, RPMBUILD_DEFAULT_LANG)) {
821  sl->sl_lines[t->t_startx] = _free(sl->sl_lines[t->t_startx]);
822  continue;
823  }
824  sl->sl_lines[t->t_startx + 1] = xstrdup(msgstr);
825  if (t->t_nlines > 2)
826  sl->sl_lines[t->t_startx + 2] = xstrdup("\n\n");
827  /*@switchbreak@*/ break;
828  }
829  }
830  msgstr = _free(msgstr);
831 
832  for (i = 0; i < sl->sl_nlines; i++) {
833  const char * s = sl->sl_lines[i];
834  if (s == NULL)
835  continue;
836  printf("%s", s);
837  if (strchr(s, '\n') == NULL && s[strlen(s)-1] != '\n')
838  printf("\n");
839  }
840 }
841 
846 static void
848  /*@globals fileSystem, internalState @*/
849  /*@modifies spec->sl->sl_lines[], spec->packages->header,
850  fileSystem, internalState @*/
851 {
852  speclines sl = spec->sl;
853  int i;
854 
855  if (sl == NULL)
856  return;
857 
858  for (i = 0; i < sl->sl_nlines; i++) {
859  const char * s = sl->sl_lines[i];
860  const char * expandedLine;
861  if (s == NULL)
862  continue;
863  expandedLine = rpmMCExpand(spec->macros, s, NULL);
864  printf("%s", expandedLine);
865  _free(expandedLine);
866  if (strchr(s, '\n') == NULL && s[strlen(s)-1] != '\n')
867  printf("\n");
868  }
869 }
879  rpmTag progTag, rpmTag scriptTag, rpmiob iob)
880  /*@modifies h @*/
881 {
882  HE_t he = (HE_t) memset(alloca(sizeof(*he)), 0, sizeof(*he));
883  int xx;
884 
885  if (progTag !=(rpmTag) 0) {
886  static const char prog[] = "/bin/sh"; /* XXX FIXME */
887  he->tag = progTag;
888  he->t = RPM_STRING_TYPE;
889  he->p.str = prog;
890  he->c = 1;
891  xx = headerPut(h, he, 0);
892  }
893 
894  if (scriptTag != (rpmTag)0 && iob != NULL) {
895  he->tag = scriptTag;
896  he->t = RPM_STRING_TYPE;
897  he->p.str = rpmiobStr(iob);
898  he->c = 1;
899  xx = headerPut(h, he, 0);
900  }
901  return 0;
902 }
903 
910  /*@modifies spec->sourceHeader @*/
911 {
912  int xx;
913 
914  if (spec->prep != NULL)
916  tagValue("Buildprepprog"), tagValue("Buildprep"), spec->prep);
917  if (spec->build != NULL)
919  tagValue("Buildbuildprog"), tagValue("Buildbuild"), spec->build);
920  if (spec->install != NULL)
922  tagValue("Buildinstallprog"), tagValue("Buildinstall"), spec->install);
923  if (spec->check != NULL)
925  tagValue("Buildcheckprog"), tagValue("Buildcheck"), spec->check);
926  if (spec->clean != NULL)
928  tagValue("Buildcleanprog"), tagValue("Buildclean"), spec->clean);
929 
930  return 0;
931 }
932 
941 static int _specQuery(rpmts ts, QVA_t qva, const char *specName,
942  /*@null@*/ const char *target)
943  /*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
944  /*@modifies rpmGlobalMacroContext, fileSystem, internalState @*/
945 {
946  Spec spec = NULL;
947  Package pkg;
948  int res = 1; /* assume error */
949  int anyarch = (target == NULL) ? 1 : 0;
950  char * passPhrase = "";
951  int recursing = 0;
952  char *cookie = NULL;
953  int verify = 0;
954  int xx;
955 
956  /*@-mods@*/ /* FIX: make spec abstract */
957  if (parseSpec(ts, specName, "/", recursing, passPhrase,
958  cookie, anyarch, 1, verify)
959  || (spec = rpmtsSetSpec(ts, NULL)) == NULL)
960  {
962  _("query of specfile %s failed, can't parse\n"),
963  specName);
964  goto exit;
965  }
966  /*@=mods@*/
967 
968  res = 0;
969  if (specedit) {
970  printNewSpecfile(spec);
971  goto exit;
972  }
973 
974  if (printspec) {
975  printParsedSpecfile(spec);
976  goto exit;
977  }
978 
979  switch (qva->qva_source) {
980  case RPMQV_SPECSRPM:
981  xx = initSourceHeader(spec, NULL);
982  xx = initSourceHeaderScriptlets(spec);
983  xx = qva->qva_showPackage(qva, ts, spec->sourceHeader);
984  break;
985  default:
986  case RPMQV_SPECFILE:
987  for (pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
988  /* If no target was specified, display all packages.
989  * Packages with empty file lists are not produced.
990  */
991  /* XXX DIEDIEDIE: this logic looks flawed. */
992  if (target == NULL || pkg->fileList != NULL)
993  xx = qva->qva_showPackage(qva, ts, pkg->header);
994  }
995  break;
996  }
997 
998 exit:
999  spec = freeSpec(spec);
1000  return res;
1001 }
1002 
1003 int rpmspecQuery(rpmts ts, QVA_t qva, const char * arg)
1004 {
1005  int res = 1;
1006  const char * targets = rpmcliTargets;
1007  char *target;
1008  const char * t;
1009  const char * te;
1010  int nqueries = 0;
1011 
1012  if (qva->qva_showPackage == NULL)
1013  goto exit;
1014 
1015  if (targets == NULL) {
1016  res = _specQuery(ts, qva, arg, NULL);
1017  nqueries++;
1018  goto exit;
1019  }
1020 
1022  _("Query specfile for platform(s): %s\n"), targets);
1023  for (t = targets; *t != '\0'; t = te) {
1024  /* Parse out next target platform. */
1025  if ((te = strchr(t, ',')) == NULL)
1026  te = t + strlen(t);
1027  target = alloca(te-t+1);
1028  strncpy(target, t, (te-t));
1029  target[te-t] = '\0';
1030  if (*te != '\0')
1031  te++;
1032 
1033  /* Query spec for this target platform. */
1034  rpmlog(RPMLOG_DEBUG, _(" target platform: %s\n"), target);
1035  /* Read in configuration for target. */
1036  if (t != targets) {
1037  rpmFreeMacros(NULL);
1038  rpmFreeRpmrc();
1039  (void) rpmReadConfigFiles(NULL, target);
1040  }
1041  res = _specQuery(ts, qva, arg, target);
1042  nqueries++;
1043  if (res) break;
1044  }
1045 
1046 exit:
1047  /* Restore original configuration. */
1048  if (nqueries > 1) {
1049  t = targets;
1050  if ((te = strchr(t, ',')) == NULL)
1051  te = t + strlen(t);
1052  target = alloca(te-t+1);
1053  strncpy(target, t, (te-t));
1054  target[te-t] = '\0';
1055  if (*te != '\0')
1056  te++;
1057  rpmFreeMacros(NULL);
1058  rpmFreeRpmrc();
1059  (void) rpmReadConfigFiles(NULL, target);
1060  }
1061  return res;
1062 }
rpmiob build
Definition: rpmspec.h:183
rpmTagType t
Definition: rpmtag.h:505
Package newPackage(Spec spec)
Create and initialize package control structure.
Definition: spec.c:208
char * fileName
Definition: rpmspec.h:26
void rpmFreeMacros(MacroContext mc)
Destroy macro context.
Definition: macro.c:2966
const char * str
Definition: rpmtag.h:72
rpmTag tag
Definition: rpmtag.h:504
static void specFini(void *_spec)
Definition: spec.c:551
const char * fileName
Definition: rpmspec.h:64
static spectags newSt(void)
Definition: spec.c:522
static const char * prog
Definition: parseScript.c:58
char ** sl_lines
Definition: rpmspec.h:100
rpmioPool _specPool
Definition: spec.c:629
pgpDig pgpDigFree(pgpDig dig)
Destroy a container for parsed OpenPGP packates.
Package freePackages(Package packages)
Destroy all packages associated with spec file.
Definition: spec.c:245
rpmiob clean
Definition: rpmspec.h:189
const char * sourceRpmName
Definition: rpmspec.h:162
Package next
Definition: rpmspec.h:248
OpenPGP constants and structures from RFC-2440.
rpmiob fileList
Definition: rpmspec.h:246
int noSource
Definition: rpmspec.h:159
struct OpenFileInfo * next
Definition: rpmspec.h:72
static spectags freeSt(spectags st)
Definition: spec.c:537
const char * postInFile
Definition: rpmspec.h:223
int _rpmbuildFlags
Definition: poptBT.c:53
char * xstrdup(const char *str)
Definition: rpmmalloc.c:322
spectag st_t
Definition: rpmspec.h:91
void * rpmluavFree(rpmluav var)
const char * specFullSourceName(SpecSource source)
Return a ptr to the full url of the source.
Definition: spec.c:302
int rpmReadConfigFiles(const char *file, const char *target)
Definition: rpmrc.c:1099
const char * rootURL
Definition: rpmspec.h:115
static void printNewSpecfile(Spec spec)
Print copy of spec file, filling in Group/Description/Summary from specspo.
Definition: spec.c:736
const char * specFile
Definition: rpmspec.h:111
Structure(s) used for file info tag sets.
int headerGet(Header h, HE_t he, unsigned int flags)
Retrieve extension or tag value from a header.
Definition: header.c:2222
void rpmluavSetListMode(rpmluav var, int flag)
char * lbuf
Definition: rpmspec.h:125
int headerPut(Header h, HE_t he, unsigned int flags)
Add or append tag container to header.
Definition: header.c:2285
rpmioItem rpmioLinkPoolItem(rpmioItem item, const char *msg, const char *fn, unsigned ln)
Increment a pool item refcount.
Definition: rpmmalloc.c:166
int specedit
Definition: poptQV.c:22
char * prog
Definition: rpmspec.h:30
The Header data structure.
const char * fileFile
Definition: rpmspec.h:244
headerSprintfExtension rpmHeaderFormats
Table of query format extensions.
Definition: formats.c:305
int sl_nalloc
Definition: rpmspec.h:101
rpmuint32_t num
Definition: rpmspec.h:45
rpmiob check
Definition: rpmspec.h:187
Header sourceHeader
Definition: rpmspec.h:166
void addMacro(MacroContext mc, const char *n, const char *o, const char *b, int level)
Add macro to context.
Definition: macro.c:2684
rpmfi rpmfiFree(rpmfi fi)
Destroy a file info set.
size_t lbuf_len
Definition: rpmspec.h:126
rpmiob rpmiobFree(rpmiob iob)
Destroy a I/O buffer instance.
int specSourceNum(SpecSource source)
Return the spec or source patch number.
Definition: spec.c:309
struct Source * sources
Definition: rpmspec.h:157
static void rpmlog(int code, const char *fmt,...)
Definition: rpmlog.h:299
const char ** BANames
Definition: rpmspec.h:142
Spec newSpec(void)
Create and initialize Spec structure.
Definition: spec.c:645
char * passPhrase
Definition: rpmspec.h:151
int _pkg_debug
Definition: spec.c:23
rpmds rpmdsFree(rpmds ds)
Destroy a dependency set.
static Package pkgGetPool(rpmioPool pool)
Definition: spec.c:194
struct Source * next
Definition: rpmspec.h:47
Command line option information.
Definition: rpmcli.h:634
char * headerSprintf(Header h, const char *fmt, headerTagTableEntry tags, headerSprintfExtension exts, errmsg_t *errmsg)
Return formatted output string from header tags.
Definition: hdrfmt.c:6700
void rpmluaPushTable(rpmlua _lua, const char *key,...)
void rpmluavSetValue(rpmluav var, rpmluavType type, const void *value)
const char * getSourceDir(rpmfileAttrs attr)
Return the macro directory location from source file flags.
Definition: build.c:24
int parseSpec(rpmts ts, const char *specFile, const char *rootURL, int recursing, const char *passPhrase, const char *cookie, int anyarch, int force, int verify)
Parse spec file into spec control structure.
Definition: parseSpec.c:527
int t_tag
Definition: rpmspec.h:78
#define SKIPWHITE(_x)
Definition: spec.c:36
rpmTag tagValue(const char *tagstr)
Return tag value from name.
Definition: tagname.c:446
const char * fullSource
Definition: rpmspec.h:41
rpmiob prep
Definition: rpmspec.h:181
static Spec specGetPool(rpmioPool pool)
Definition: spec.c:631
const char * source
Definition: rpmspec.h:43
Definition: rpmspec.h:39
char * alloca()
int lineNum
Definition: rpmspec.h:67
Yet Another syslog(3) API clone.
QVF_t qva_showPackage
Definition: rpmcli.h:646
Header header
Definition: rpmspec.h:210
unsigned int rpmuint32_t
Definition: rpmiotypes.h:25
struct _HE_s * HE_t
Definition: rpmtag.h:58
char * nextline
Definition: rpmspec.h:131
void * ptr
Definition: rpmtag.h:66
MacroContext rpmGlobalMacroContext
Definition: macro.c:122
rpmioItem rpmioGetPool(rpmioPool pool, size_t size)
Get unused item from pool, or alloc a new item.
Definition: rpmmalloc.c:221
int recursing
Definition: rpmspec.h:144
static speclines freeSl(speclines sl)
Definition: spec.c:507
const char * cookie
Definition: rpmspec.h:154
static speclines newSl(void)
Definition: spec.c:492
char * line
Definition: rpmspec.h:133
struct rpmfi_s * rpmfi
File info tag sets from a header, so that a header can be discarded early.
Definition: rpmfi.h:78
#define PART_SUBNAME
Definition: rpmbuild.h:48
rpmiob specialDoc
Definition: rpmspec.h:238
rpmTagData p
Definition: rpmtag.h:507
static struct TriggerFileEntry * freeTriggerFiles(struct TriggerFileEntry *p)
Definition: spec.c:46
MacroContext macros
Definition: rpmspec.h:172
struct rpmluav_s * rpmluav
Definition: rpmlua.h:54
char nextpeekc
Definition: rpmspec.h:129
const char * rpmcliTargets
Definition: poptALL.c:175
const char * tagName(rpmTag tag)
Return tag name from value.
Definition: tagname.c:436
#define SKIPNONWHITE(_x)
Definition: spec.c:37
rpmuint32_t sstates[RPMSCRIPT_MAX]
Definition: rpmspec.h:177
int specSourceFlags(SpecSource source)
Return flags set for the source.
Definition: spec.c:316
struct OpenFileInfo * newOpenFileInfo(void)
Definition: spec.c:716
struct TriggerFileEntry * triggerFiles
Definition: rpmspec.h:241
Structure(s) used for dependency tag sets.
int t_startx
Definition: rpmspec.h:79
int autoProv
Definition: rpmspec.h:217
int anyarch
Definition: rpmspec.h:148
rpmQVSources qva_source
Definition: rpmcli.h:635
rpmuint32_t smetrics[RPMSCRIPT_MAX]
Definition: rpmspec.h:178
static int initSourceHeaderScriptlets(Spec spec)
Add expanded build scriptlets to srpm header.
Definition: spec.c:909
struct Spec_s * Spec
Definition: rpmtypes.h:23
const char * rpmGenPath(const char *urlroot, const char *urlmdir, const char *urlfile)
Merge 3 args into path, any or all of which may be a url.
Definition: macro.c:3356
rpmioPool _pkgPool
Definition: spec.c:192
rpmRC lookupPackage(Spec spec, const char *name, int flag, Package *pkgp)
Find sub-package control structure by name.
Definition: spec.c:82
rpmTagCount c
Definition: rpmtag.h:508
rpmluav rpmluavNew(void)
The structure used to store values parsed from a spec file.
Definition: rpmspec.h:108
Header headerFree(Header h)
Dereference a header instance.
char * rpmExpand(const char *arg,...)
Return (malloc&#39;ed) concatenated macro expansion(s).
Definition: macro.c:3117
Spec freeSpec(Spec spec)
Destroy a spec file control structure.
const char * buildSubdir
Definition: rpmspec.h:113
const char * preInFile
Definition: rpmspec.h:221
const char * t_lang
Definition: rpmspec.h:82
struct Package_s * Package
Definition: rpmspec.h:15
SpecSource getSource(Spec spec, int num)
Return a source control structure.
Definition: spec.c:279
void rpmluaDelVar(rpmlua _lua, const char *key,...)
struct TriggerFileEntry * next
Definition: rpmspec.h:32
static int initSourceHeaderScriptlet(Header h, rpmTag progTag, rpmTag scriptTag, rpmiob iob)
Add expanded build scriptlet to srpm header.
Definition: spec.c:878
size_t nfoo
Definition: rpmspec.h:191
int numSources
Definition: rpmspec.h:158
char * script
Definition: rpmspec.h:28
Package freePackage(Package pkg)
Destroy a package control structure.
struct ReadLevelEntry * readStack
Definition: rpmspec.h:137
Spec rpmtsSetSpec(rpmts ts, Spec spec)
Set a spec control structure in transaction set.
Definition: rpmts.c:1395
spectags st
Definition: rpmspec.h:120
Routines to read and write packages.
int BACount
Definition: rpmspec.h:143
const char * specSourceName(SpecSource source)
Return a ptr to the source file name.
Definition: spec.c:295
const char * postUnFile
Definition: rpmspec.h:227
static int _specQuery(rpmts ts, QVA_t qva, const char *specName, const char *target)
Parse a spec file, and query the resultant header.
Definition: spec.c:941
#define RMIL_SPEC
Definition: rpmmacro.h:56
static void printParsedSpecfile(Spec spec)
Print parsed copy of spec file with expanded macros.
Definition: spec.c:847
enum rpmRC_e rpmRC
RPM return codes.
char * rpmiobStr(rpmiob iob)
Return I/O buffer (as string).
Definition: rpmiob.c:113
Package packages
Definition: rpmspec.h:197
struct rpmioItem_s _item
Definition: rpmspec.h:208
static void pkgFini(void *_pkg)
Definition: spec.c:161
Definition: rpmtag.h:503
int parseNum(const char *line, rpmuint32_t *res)
Parse a number.
Definition: misc.c:11
static struct Source * findSource(Spec spec, rpmuint32_t num, int flag)
Definition: spec.c:259
const char * t_msgid
Definition: rpmspec.h:84
static int xisdigit(int c)
Definition: rpmiotypes.h:437
Spec * BASpecs
Definition: rpmspec.h:140
int timeCheck
Definition: rpmspec.h:152
char * readPtr
Definition: rpmspec.h:70
rpmioPool rpmioNewPool(const char *name, size_t size, int limit, int flags, char *(*dbg)(void *item), void(*init)(void *item), void(*fini)(void *item))
Create a memory pool.
Definition: rpmmalloc.c:110
rpmRC(* _parseRCPOT)(Spec spec, Package pkg, const char *field, rpmTag tagN, rpmuint32_t index, rpmsenseFlags tagflags)
Definition: rpmspec.h:174
int rpmspecQuery(rpmts ts, QVA_t qva, const char *arg)
Function to query spec file(s).
Definition: spec.c:1003
char * stpcpy(char *dest, const char *src)
struct rpmts_s * rpmts
The RPM Transaction Set.
Definition: rpmtypes.h:14
void rpmluaSetVar(rpmlua _lua, rpmluav var)
static void * _free(const void *p)
Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
Definition: rpmiotypes.h:647
struct rpmiob_s * rpmiob
Definition: rpmiotypes.h:57
Structures and prototypes used for an "rpmts" transaction set.
struct rpmioItem_s _item
Definition: rpmspec.h:109
int sl_nlines
Definition: rpmspec.h:102
tagStore_t tagStoreFree(tagStore_t dbiTags, size_t dbiNTags)
Destroy tagStore array.
Definition: tagname.c:473
rpmRC parseRCPOT(Spec spec, Package pkg, const char *field, rpmTag tagN, rpmuint32_t index, rpmsenseFlags tagflags)
Parse dependency relations from spec file and/or autogenerated output buffer.
Definition: parseReqs.c:20
rpmds ds
Definition: rpmspec.h:212
static struct Source * freeSources(struct Source *s)
Destroy source component chain.
Definition: spec.c:68
int t_nlines
Definition: rpmspec.h:80
void closeSpec(Spec spec)
Stop reading from spec file, freeing resources.
Definition: parseSpec.c:484
int lineNum
Definition: rpmspec.h:134
speclines sl
Definition: rpmspec.h:118
rpmfi fi
Definition: rpmspec.h:168
const char * verifyFile
Definition: rpmspec.h:233
struct rpmlua_s * rpmlua
Definition: rpmlua.h:53
int force
Definition: rpmspec.h:147
FD_t fd
Definition: rpmspec.h:66
static const char * name
#define _(Text)
Definition: system.h:30
The structure used to store values for a package.
Definition: rpmspec.h:207
const char * preUnFile
Definition: rpmspec.h:225
rpmiob install
Definition: rpmspec.h:185
char readBuf[BUFSIZ]
Definition: rpmspec.h:68
#define xmalloc
Definition: system.h:33
int st_nalloc
Definition: rpmspec.h:92
rpmfi fi
Definition: rpmspec.h:214
enum rpmTag_e rpmTag
Definition: rpmtag.h:471
#define SKIPSPACE(s)
Definition: rpmbuild.h:45
tagStore_t foo
Definition: rpmspec.h:193
int parseNoSource(Spec spec, const char *field, rpmTag tag)
parseNoSource.
Definition: spec.c:321
#define RPMBUILD_DEFAULT_LANG
Definition: rpmspec.h:35
int st_ntags
Definition: rpmspec.h:93
int toplevel
Definition: rpmspec.h:145
struct OpenFileInfo * fileStack
Definition: rpmspec.h:123
Header headerNew(void)
Create new (empty) header instance.
Definition: header.c:180
int initSourceHeader(Spec spec, rpmiob *sfp)
Create and initialize header for source package.
Definition: files.c:2552
int _spec_debug
Definition: spec.c:26
int rpmExpandNumeric(const char *arg)
Return macro expansion as a numeric value.
Definition: macro.c:3191
int printspec
Definition: poptQV.c:25
void * dig
Definition: rpmspec.h:195
int flags
Definition: rpmspec.h:44
void rpmFreeRpmrc(void)
Definition: rpmrc.c:1008
struct ReadLevelEntry * next
Definition: rpmspec.h:56
int SpecSourceCount(Spec spec)
Return the count of source set in specfile.
Definition: spec.c:272
unsigned char * sourcePkgId
Definition: rpmspec.h:164
int autoReq
Definition: rpmspec.h:216
const char * sanityCheckFile
Definition: rpmspec.h:235
char * rpmMCExpand(MacroContext mc, const char *arg,...)
Return (malloc&#39;ed) concatenated macro expansion(s) in a context.
Definition: macro.c:3154
int addSource(Spec spec, Package pkg, const char *field, rpmTag tag)
addSource.
Definition: spec.c:365