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