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", "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 /*@=nullassign@*/
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 /*@unchecked@*/ /*@observer@*/
00058 static struct _rpmnsProbes_s {
00059 /*@observer@*/ /*@relnull@*/
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 /*@=boundsread@*/
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 }

Generated on Wed Feb 6 22:31:49 2008 for rpm by  doxygen 1.5.1