lib/rpmns.c

Go to the documentation of this file.
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 }

Generated on Mon Aug 23 10:43:21 2010 for rpm by  doxygen 1.5.1