00001
00004 #include "system.h"
00005
00006 #include <rpmio.h>
00007 #include <rpmmacro.h>
00008
00009 #define _RPMEVR_INTERNAL
00010 #include <rpmevr.h>
00011 #define _RPMNS_INTERNAL
00012 #include <rpmns.h>
00013
00014 #include "debug.h"
00015
00016
00017 int _rpmns_debug = 0;
00018
00019
00020 const char *_rpmns_N_at_A = ".";
00021
00022
00023
00024 static const char *rpmnsArches[] = {
00025 "i386", "i486", "i586", "i686", "athlon", "pentium3", "pentium4", "x86_64", "amd64", "ia32e",
00026 "alpha", "alphaev5", "alphaev56", "alphapca56", "alphaev6", "alphaev67",
00027 "sparc", "sun4", "sun4m", "sun4c", "sun4d", "sparcv8", "sparcv9",
00028 "sparc64", "sun4u",
00029 "mips", "mipsel", "IP",
00030 "ppc", "ppciseries", "ppcpseries",
00031 "ppc64", "ppc64iseries", "ppc64pseries",
00032 "m68k",
00033 "rs6000",
00034 "ia64",
00035 "armv3l", "armv4b", "armv4l",
00036 "armv5teb", "armv5tel",
00037 "s390", "i370", "s390x",
00038 "sh", "xtensa",
00039 "noarch", "fat",
00040 NULL,
00041 };
00042
00043
00044 nsType rpmnsArch(const char * str)
00045 {
00046 const char ** av;
00047 for (av = rpmnsArches; *av != NULL; av++) {
00048 if (!strcmp(str, *av))
00049 return RPMNS_TYPE_ARCH;
00050 }
00051 return RPMNS_TYPE_UNKNOWN;
00052 }
00053
00057
00058 static struct _rpmnsProbes_s {
00059
00060 const char * NS;
00061 nsType Type;
00062 } rpmnsProbes[] = {
00063 { "rpmlib", RPMNS_TYPE_RPMLIB },
00064 { "cpuinfo", RPMNS_TYPE_CPUINFO },
00065 { "getconf", RPMNS_TYPE_GETCONF },
00066 { "uname", RPMNS_TYPE_UNAME },
00067 { "soname", RPMNS_TYPE_SONAME },
00068 { "user", RPMNS_TYPE_USER },
00069 { "group", RPMNS_TYPE_GROUP },
00070 { "mounted", RPMNS_TYPE_MOUNTED },
00071 { "diskspace", RPMNS_TYPE_DISKSPACE },
00072 { "digest", RPMNS_TYPE_DIGEST },
00073 { "gnupg", RPMNS_TYPE_GNUPG },
00074 { "macro", RPMNS_TYPE_MACRO },
00075 { "envvar", RPMNS_TYPE_ENVVAR },
00076 { "running", RPMNS_TYPE_RUNNING },
00077 { "exists", RPMNS_TYPE_ACCESS },
00078 { "executable", RPMNS_TYPE_ACCESS },
00079 { "readable", RPMNS_TYPE_ACCESS },
00080 { "writable", RPMNS_TYPE_ACCESS },
00081 { "RWX", RPMNS_TYPE_ACCESS },
00082 { "RWx", RPMNS_TYPE_ACCESS },
00083 { "RW_", RPMNS_TYPE_ACCESS },
00084 { "RwX", RPMNS_TYPE_ACCESS },
00085 { "Rwx", RPMNS_TYPE_ACCESS },
00086 { "Rw_", RPMNS_TYPE_ACCESS },
00087 { "R_X", RPMNS_TYPE_ACCESS },
00088 { "R_x", RPMNS_TYPE_ACCESS },
00089 { "R__", RPMNS_TYPE_ACCESS },
00090 { "rWX", RPMNS_TYPE_ACCESS },
00091 { "rWx", RPMNS_TYPE_ACCESS },
00092 { "rW_", RPMNS_TYPE_ACCESS },
00093 { "rwX", RPMNS_TYPE_ACCESS },
00094 { "rwx", RPMNS_TYPE_ACCESS },
00095 { "rw_", RPMNS_TYPE_ACCESS },
00096 { "r_X", RPMNS_TYPE_ACCESS },
00097 { "r_x", RPMNS_TYPE_ACCESS },
00098 { "r__", RPMNS_TYPE_ACCESS },
00099 { "_WX", RPMNS_TYPE_ACCESS },
00100 { "_Wx", RPMNS_TYPE_ACCESS },
00101 { "_W_", RPMNS_TYPE_ACCESS },
00102 { "_wX", RPMNS_TYPE_ACCESS },
00103 { "_wx", RPMNS_TYPE_ACCESS },
00104 { "_w_", RPMNS_TYPE_ACCESS },
00105 { "__X", RPMNS_TYPE_ACCESS },
00106 { "__x", RPMNS_TYPE_ACCESS },
00107 { "___", RPMNS_TYPE_ACCESS },
00108 { NULL, 0 }
00109 };
00110
00111 nsType rpmnsProbe(const char * str)
00112 {
00113 const struct _rpmnsProbes_s * av;
00114 size_t sn = strlen(str);
00115 size_t nb;
00116
00117 if (sn >= 5 && str[sn-1] == ')')
00118 for (av = rpmnsProbes; av->NS != NULL; av++) {
00119 nb = strlen(av->NS);
00120 if (sn > nb && str[nb] == '(' && !strncmp(str, av->NS, nb))
00121 return av->Type;
00122 }
00123 return RPMNS_TYPE_UNKNOWN;
00124 }
00125
00126
00127 nsType rpmnsClassify(const char * str)
00128 {
00129 const char * s;
00130 nsType Type = RPMNS_TYPE_STRING;
00131
00132 if (*str == '!')
00133 str++;
00134 if (*str == '/')
00135 return RPMNS_TYPE_PATH;
00136 s = str + strlen(str);
00137 if (str[0] == '%' && str[1] == '{' && s[-1] == '}')
00138 return RPMNS_TYPE_FUNCTION;
00139 if ((s - str) > 3 && s[-3] == '.' && s[-2] == 's' && s[-1] == 'o')
00140 return RPMNS_TYPE_DSO;
00141 Type = rpmnsProbe(str);
00142 if (Type != RPMNS_TYPE_UNKNOWN)
00143 return Type;
00144 for (s = str; *s; s++) {
00145 if (s[0] == '(' || s[strlen(s)-1] == ')')
00146 return RPMNS_TYPE_NAMESPACE;
00147 if (s[0] == '.' && s[1] == 's' && s[2] == 'o')
00148 return RPMNS_TYPE_DSO;
00149 if (s[0] == '.' && xisdigit(s[-1]) && xisdigit(s[1]))
00150 return RPMNS_TYPE_VERSION;
00151 if (_rpmns_N_at_A && _rpmns_N_at_A[0]) {
00152 if (s[0] == _rpmns_N_at_A[0] && rpmnsArch(s+1))
00153 return RPMNS_TYPE_ARCH;
00154 }
00155 if (s[0] == '.')
00156 return RPMNS_TYPE_COMPOUND;
00157 }
00158 return RPMNS_TYPE_STRING;
00159 }
00160
00161 int rpmnsParse(const char * str, rpmns ns)
00162 {
00163 char *t;
00164 ns->str = t = rpmExpand(str, NULL);
00165 ns->Type = rpmnsClassify(ns->str);
00166 switch (ns->Type) {
00167 case RPMNS_TYPE_ARCH:
00168 ns->NS = NULL;
00169 ns->N = ns->str;
00170 if (ns->N[0] == '!')
00171 ns->N++;
00172 if ((t = strrchr(t, _rpmns_N_at_A[0])) != NULL)
00173 *t++ = '\0';
00174 ns->A = t;
00175 break;
00176 case RPMNS_TYPE_RPMLIB:
00177 case RPMNS_TYPE_CPUINFO:
00178 case RPMNS_TYPE_GETCONF:
00179 case RPMNS_TYPE_UNAME:
00180 case RPMNS_TYPE_SONAME:
00181 case RPMNS_TYPE_ACCESS:
00182 case RPMNS_TYPE_USER:
00183 case RPMNS_TYPE_GROUP:
00184 case RPMNS_TYPE_MOUNTED:
00185 case RPMNS_TYPE_DISKSPACE:
00186 case RPMNS_TYPE_DIGEST:
00187 case RPMNS_TYPE_GNUPG:
00188 case RPMNS_TYPE_MACRO:
00189 case RPMNS_TYPE_ENVVAR:
00190 case RPMNS_TYPE_RUNNING:
00191 ns->NS = ns->str;
00192 if (ns->NS[0] == '!')
00193 ns->NS++;
00194 if ((t = strchr(t, '(')) != NULL)
00195 *t++ = '\0';
00196 ns->N = t;
00197 t[strlen(t)-1] = '\0';
00198 ns->A = NULL;
00199 break;
00200 case RPMNS_TYPE_UNKNOWN:
00201 case RPMNS_TYPE_STRING:
00202 case RPMNS_TYPE_PATH:
00203 case RPMNS_TYPE_DSO:
00204 case RPMNS_TYPE_FUNCTION:
00205 case RPMNS_TYPE_VERSION:
00206 case RPMNS_TYPE_COMPOUND:
00207 case RPMNS_TYPE_NAMESPACE:
00208 case RPMNS_TYPE_TAG:
00209 default:
00210 ns->NS = NULL;
00211 ns->N = ns->str;
00212 if (ns->N[0] == '!')
00213 ns->N++;
00214 ns->A = NULL;
00215 break;
00216 }
00217 return 0;
00218 }