rpm  4.5
rpmns.c
Go to the documentation of this file.
1 
4 #include "system.h"
5 
6 #include <rpmio.h>
7 #include <rpmmacro.h>
8 
9 #define _RPMEVR_INTERNAL
10 #include <rpmevr.h>
11 #define _RPMNS_INTERNAL
12 #include <rpmns.h>
13 
14 #include "debug.h"
15 
16 /*@unchecked@*/
17 int _rpmns_debug = 0;
18 
19 /*@unchecked@*/ /*@observer@*/
20 const char *_rpmns_N_at_A = ".";
21 
22 /*@-nullassign@*/
23 /*@unchecked@*/ /*@observer@*/
24 static const char *rpmnsArches[] = {
25  "i386", "i486", "i586", "i686", "athlon", "pentium3", "pentium4",
26  "x86_64", "amd64", "ia32e",
27  "alpha", "alphaev5", "alphaev56", "alphapca56", "alphaev6", "alphaev67",
28  "sparc", "sun4", "sun4m", "sun4c", "sun4d", "sparcv8",
29  "sparcv9", "sparcv9v",
30  "sparc64", "sun4u", "sparc64v",
31  "mips", "mipsel", "IP",
32  "ppc", "ppciseries", "ppcpseries",
33  "ppc64", "ppc64iseries", "ppc64pseries",
34  "m68k",
35  "rs6000",
36  "ia64",
37  "armv3l", "armv4b", "armv4l",
38  "armv5teb", "armv5tel", "armv5tejl",
39  "armv6l",
40  "s390", "i370", "s390x",
41  "sh", "xtensa",
42  "noarch", "fat",
43  NULL,
44 };
45 /*@=nullassign@*/
46 
47 nsType rpmnsArch(const char * str)
48 {
49  const char ** av;
50  for (av = rpmnsArches; *av != NULL; av++) {
51  if (!strcmp(str, *av))
52  return RPMNS_TYPE_ARCH;
53  }
54  return RPMNS_TYPE_UNKNOWN;
55 }
56 
60 /*@unchecked@*/ /*@observer@*/
61 static struct _rpmnsProbes_s {
62 /*@observer@*/ /*@relnull@*/
63  const char * NS;
65 } rpmnsProbes[] = {
66  { "rpmlib", RPMNS_TYPE_RPMLIB },
67  { "cpuinfo", RPMNS_TYPE_CPUINFO },
68  { "getconf", RPMNS_TYPE_GETCONF },
69  { "uname", RPMNS_TYPE_UNAME },
70  { "soname", RPMNS_TYPE_SONAME },
71  { "user", RPMNS_TYPE_USER },
72  { "group", RPMNS_TYPE_GROUP },
73  { "mounted", RPMNS_TYPE_MOUNTED },
74  { "diskspace", RPMNS_TYPE_DISKSPACE },
75  { "digest", RPMNS_TYPE_DIGEST },
76  { "gnupg", RPMNS_TYPE_GNUPG },
77  { "macro", RPMNS_TYPE_MACRO },
78  { "envvar", RPMNS_TYPE_ENVVAR },
79  { "running", RPMNS_TYPE_RUNNING },
80  { "exists", RPMNS_TYPE_ACCESS },
81  { "executable", RPMNS_TYPE_ACCESS },
82  { "readable", RPMNS_TYPE_ACCESS },
83  { "writable", RPMNS_TYPE_ACCESS },
84  { "RWX", RPMNS_TYPE_ACCESS },
85  { "RWx", RPMNS_TYPE_ACCESS },
86  { "RW_", RPMNS_TYPE_ACCESS },
87  { "RwX", RPMNS_TYPE_ACCESS },
88  { "Rwx", RPMNS_TYPE_ACCESS },
89  { "Rw_", RPMNS_TYPE_ACCESS },
90  { "R_X", RPMNS_TYPE_ACCESS },
91  { "R_x", RPMNS_TYPE_ACCESS },
92  { "R__", RPMNS_TYPE_ACCESS },
93  { "rWX", RPMNS_TYPE_ACCESS },
94  { "rWx", RPMNS_TYPE_ACCESS },
95  { "rW_", RPMNS_TYPE_ACCESS },
96  { "rwX", RPMNS_TYPE_ACCESS },
97  { "rwx", RPMNS_TYPE_ACCESS },
98  { "rw_", RPMNS_TYPE_ACCESS },
99  { "r_X", RPMNS_TYPE_ACCESS },
100  { "r_x", RPMNS_TYPE_ACCESS },
101  { "r__", RPMNS_TYPE_ACCESS },
102  { "_WX", RPMNS_TYPE_ACCESS },
103  { "_Wx", RPMNS_TYPE_ACCESS },
104  { "_W_", RPMNS_TYPE_ACCESS },
105  { "_wX", RPMNS_TYPE_ACCESS },
106  { "_wx", RPMNS_TYPE_ACCESS },
107  { "_w_", RPMNS_TYPE_ACCESS },
108  { "__X", RPMNS_TYPE_ACCESS },
109  { "__x", RPMNS_TYPE_ACCESS },
110  { "___", RPMNS_TYPE_ACCESS },
111  { NULL, 0 }
112 };
113 
114 nsType rpmnsProbe(const char * str)
115 {
116  const struct _rpmnsProbes_s * av;
117  size_t sn = strlen(str);
118  size_t nb;
119 
120  if (sn >= 5 && str[sn-1] == ')')
121  for (av = rpmnsProbes; av->NS != NULL; av++) {
122  nb = strlen(av->NS);
123  if (sn > nb && str[nb] == '(' && !strncmp(str, av->NS, nb))
124  return av->Type;
125  }
126  return RPMNS_TYPE_UNKNOWN;
127 }
128 
129 /*@=boundsread@*/
130 nsType rpmnsClassify(const char * str)
131 {
132  const char * s;
134 
135  if (*str == '!')
136  str++;
137  if (*str == '/')
138  return RPMNS_TYPE_PATH;
139  s = str + strlen(str);
140  if (str[0] == '%' && str[1] == '{' && s[-1] == '}')
141  return RPMNS_TYPE_FUNCTION;
142  if ((s - str) > 3 && s[-3] == '.' && s[-2] == 's' && s[-1] == 'o')
143  return RPMNS_TYPE_DSO;
144  Type = rpmnsProbe(str);
145  if (Type != RPMNS_TYPE_UNKNOWN)
146  return Type;
147  for (s = str; *s; s++) {
148  if (s[0] == '(' || s[strlen(s)-1] == ')')
149  return RPMNS_TYPE_NAMESPACE;
150  if (s[0] == '.' && s[1] == 's' && s[2] == 'o')
151  return RPMNS_TYPE_DSO;
152  if (s[0] == '.' && xisdigit(s[-1]) && xisdigit(s[1]))
153  return RPMNS_TYPE_VERSION;
154  if (_rpmns_N_at_A && _rpmns_N_at_A[0]) {
155  if (s[0] == _rpmns_N_at_A[0] && rpmnsArch(s+1))
156  return RPMNS_TYPE_ARCH;
157  }
158  if (s[0] == '.')
159  return RPMNS_TYPE_COMPOUND;
160  }
161  return RPMNS_TYPE_STRING;
162 }
163 
164 int rpmnsParse(const char * str, rpmns ns)
165 {
166  char *t;
167  ns->str = t = rpmExpand(str, NULL);
168  ns->Type = rpmnsClassify(ns->str);
169  switch (ns->Type) {
170  case RPMNS_TYPE_ARCH:
171  ns->NS = NULL;
172  ns->N = ns->str;
173  if (ns->N[0] == '!')
174  ns->N++;
175  if ((t = strrchr(t, _rpmns_N_at_A[0])) != NULL)
176  *t++ = '\0';
177  ns->A = t;
178  break;
179  case RPMNS_TYPE_RPMLIB:
180  case RPMNS_TYPE_CPUINFO:
181  case RPMNS_TYPE_GETCONF:
182  case RPMNS_TYPE_UNAME:
183  case RPMNS_TYPE_SONAME:
184  case RPMNS_TYPE_ACCESS:
185 #if 0
186  case RPMNS_TYPE_USER:
187  case RPMNS_TYPE_GROUP:
188 #endif
189  case RPMNS_TYPE_MOUNTED:
191  case RPMNS_TYPE_DIGEST:
192  case RPMNS_TYPE_GNUPG:
193  case RPMNS_TYPE_MACRO:
194  case RPMNS_TYPE_ENVVAR:
195  case RPMNS_TYPE_RUNNING:
196  ns->NS = ns->str;
197  if (ns->NS[0] == '!')
198  ns->NS++;
199  if ((t = strchr(t, '(')) != NULL)
200  *t++ = '\0';
201  ns->N = t;
202  t[strlen(t)-1] = '\0';
203  ns->A = NULL;
204  break;
205  case RPMNS_TYPE_UNKNOWN:
206  case RPMNS_TYPE_STRING:
207  case RPMNS_TYPE_PATH:
208  case RPMNS_TYPE_DSO:
209  case RPMNS_TYPE_FUNCTION:
210  case RPMNS_TYPE_VERSION:
211  case RPMNS_TYPE_COMPOUND:
213  case RPMNS_TYPE_TAG:
214  default:
215  ns->NS = NULL;
216  ns->N = ns->str;
217  if (ns->N[0] == '!')
218  ns->N++;
219  ns->A = NULL;
220  break;
221  }
222  return 0;
223 }