rpm  5.2.1
parseReqs.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 #define _RPMEVR_INTERNAL
12 #include "rpmbuild.h"
13 #include "debug.h"
14 
15 /*@access EVR_t @*/
16 
17 #define SKIPWHITE(_x) {while(*(_x) && (xisspace(*_x) || *(_x) == ',')) (_x)++;}
18 #define SKIPNONWHITE(_x){while(*(_x) &&!(xisspace(*_x) || *(_x) == ',')) (_x)++;}
19 
20 rpmRC parseRCPOT(Spec spec, Package pkg, const char *field, rpmTag tagN,
21  rpmuint32_t index, rpmsenseFlags tagflags)
22 {
23  const char *r, *re, *v, *ve;
24  char * N, * EVR;
25  rpmsenseFlags Flags;
26  Header h;
27 
28  switch (tagN) {
30  tagflags |= RPMSENSE_PROVIDES;
31  h = pkg->header;
32  break;
34  tagflags |= RPMSENSE_OBSOLETES;
35  h = pkg->header;
36  break;
38  tagflags |= RPMSENSE_CONFLICTS;
39  h = pkg->header;
40  break;
42  tagflags |= RPMSENSE_CONFLICTS;
43  h = spec->sourceHeader;
44  break;
45  case RPMTAG_PREREQ:
46  tagflags |= RPMSENSE_ANY;
47  h = pkg->header;
48  break;
50  tagflags |= RPMSENSE_TRIGGERPREIN;
51  h = pkg->header;
52  break;
53  case RPMTAG_TRIGGERIN:
54  tagflags |= RPMSENSE_TRIGGERIN;
55  h = pkg->header;
56  break;
58  tagflags |= RPMSENSE_TRIGGERPOSTUN;
59  h = pkg->header;
60  break;
61  case RPMTAG_TRIGGERUN:
62  tagflags |= RPMSENSE_TRIGGERUN;
63  h = pkg->header;
64  break;
67  tagflags |= RPMSENSE_MISSINGOK;
68  h = spec->sourceHeader;
69  break;
70  case RPMTAG_BUILDPREREQ:
72  tagflags |= RPMSENSE_ANY;
73  h = spec->sourceHeader;
74  break;
76  tagflags |= RPMSENSE_PROVIDES;
77  h = spec->sourceHeader;
78  break;
80  tagflags |= RPMSENSE_OBSOLETES;
81  h = spec->sourceHeader;
82  break;
83  default:
85  tagflags |= RPMSENSE_ANY;
86  h = pkg->header;
87  break;
88  }
89 
90  for (r = field; *r != '\0'; r = re) {
91  size_t nr;
92  SKIPWHITE(r);
93  if (*r == '\0')
94  break;
95 
96  Flags = (tagflags & ~RPMSENSE_SENSEMASK);
97 
98  /* Tokens must begin with alphanumeric, _, or / */
99  nr = strlen(r);
100  if (!(xisalnum(r[0]) || r[0] == '_' || r[0] == '/'
101  || (nr > 2 && r[0] == '!')
102  || (nr > 3 && r[0] == '%' && r[1] == '{' && r[nr-1] == '}')))
103  {
105  _("line %d: Dependency \"%s\" must begin with alpha-numeric, '_' or '/': %s\n"),
106  spec->lineNum, spec->line, r);
107  return RPMRC_FAIL;
108  }
109 
110  re = r;
111  SKIPNONWHITE(re);
112  N = xmalloc((re-r) + 1);
113  strncpy(N, r, (re-r));
114  N[re-r] = '\0';
115 
116  /* Parse EVR */
117  v = re;
118  SKIPWHITE(v);
119  ve = v;
120  SKIPNONWHITE(ve);
121 
122  re = v; /* ==> next token (if no EVR found) starts here */
123 
124  /* Check for possible logical operator */
125  if (ve > v) {
126 /*@-mods@*/
127  rpmsenseFlags F = rpmEVRflags(v, &ve);
128 /*@=mods@*/
129  if (F && r[0] == '/') {
131  _("line %d: Versioned file name not permitted: %s\n"),
132  spec->lineNum, spec->line);
133  return RPMRC_FAIL;
134  }
135  if (F) {
136  /* now parse EVR */
137  v = ve;
138  SKIPWHITE(v);
139  ve = v;
140  SKIPNONWHITE(ve);
141  }
142  Flags &= ~RPMSENSE_SENSEMASK;
143  Flags |= F;
144  }
145 
146  if (Flags & RPMSENSE_SENSEMASK) {
147  if (*v == '\0' || ve == v) {
148  rpmlog(RPMLOG_ERR, _("line %d: Version required: %s\n"),
149  spec->lineNum, spec->line);
150  return RPMRC_FAIL;
151  }
152  EVR = xmalloc((ve-v) + 1);
153  strncpy(EVR, v, (ve-v));
154  EVR[ve-v] = '\0';
155  re = ve; /* ==> next token after EVR string starts here */
156  } else
157  EVR = NULL;
158 
159  /* Make sure that EVR is parseable during install. */
160  if (EVR != NULL) {
161  EVR_t evr = memset(alloca(sizeof(*evr)), 0, sizeof(*evr));
162  int xx = rpmEVRparse(xstrdup(EVR), evr);
163 
164  evr->str = _free(evr->str);
165  if (xx != 0) {
167  _("line %d: EVR does not parse: %s\n"),
168  spec->lineNum, spec->line);
169  N = _free(N);
170  EVR = _free(EVR);
171  return RPMRC_FAIL;
172  }
173  }
174 
175  (void) addReqProv(spec, h, tagN, N, EVR, Flags, index);
176 
177  N = _free(N);
178  EVR = _free(EVR);
179 
180  }
181 
182  return RPMRC_OK;
183 }