rpm
4.5
|
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 /*@unchecked@*/ 00017 int _rpmns_debug = 0; 00018 00019 /*@unchecked@*/ /*@observer@*/ 00020 const char *_rpmns_N_at_A = "."; 00021 00022 /*@-nullassign@*/ 00023 /*@unchecked@*/ /*@observer@*/ 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 /*@=nullassign@*/ 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 /*@unchecked@*/ /*@observer@*/ 00061 static struct _rpmnsProbes_s { 00062 /*@observer@*/ /*@relnull@*/ 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 /*@=boundsread@*/ 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 }