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