00001
00005 #include "system.h"
00006
00007 #include <rpmlib.h>
00008 #include "debug.h"
00009
00010
00011
00012
00019 static int tagCmpName(const void * avp, const void * bvp)
00020
00021 {
00022 headerTagTableEntry a = *(headerTagTableEntry *) avp;
00023 headerTagTableEntry b = *(headerTagTableEntry *) bvp;
00024 return strcmp(a->name, b->name);
00025 }
00026
00033 static int tagCmpValue(const void * avp, const void * bvp)
00034
00035 {
00036 headerTagTableEntry a = *(headerTagTableEntry *) avp;
00037 headerTagTableEntry b = *(headerTagTableEntry *) bvp;
00038 int ret = (a->val - b->val);
00039
00040 if (ret == 0)
00041 ret = (strlen(b->name) - strlen(a->name));
00042 return ret;
00043 }
00044
00052 static int tagLoadIndex(headerTagTableEntry ** ipp, int * np,
00053 int (*cmp) (const void * avp, const void * bvp))
00054
00055 {
00056 headerTagTableEntry tte, *ip;
00057 int n = 0;
00058
00059 ip = xcalloc(rpmTagTableSize, sizeof(*ip));
00060 n = 0;
00061
00062 for (tte = (headerTagTableEntry)rpmTagTable; tte->name != NULL; tte++) {
00063 ip[n] = tte;
00064 n++;
00065 }
00066 assert(n == rpmTagTableSize);
00067
00068
00069 if (n > 1)
00070 qsort(ip, n, sizeof(*ip), cmp);
00071 *ipp = ip;
00072 *np = n;
00073 return 0;
00074 }
00075
00076
00077
00078 static const char * _tagName(int tag)
00079 ;
00080 static int _tagType(int tag)
00081 ;
00082 static int _tagValue(const char * tagstr)
00083 ;
00084
00085
00086 static struct headerTagIndices_s _rpmTags = {
00087 tagLoadIndex,
00088 NULL, 0, tagCmpName, _tagValue,
00089 NULL, 0, tagCmpValue, _tagName, _tagType,
00090 };
00091
00092
00093
00094 headerTagIndices rpmTags = &_rpmTags;
00095
00096
00097 static const char * _tagName(int tag)
00098 {
00099 static char nameBuf[128];
00100 const struct headerTagTableEntry_s *t;
00101 int comparison, i, l, u;
00102 int xx;
00103 char *s;
00104
00105 if (_rpmTags.byValue == NULL)
00106 xx = tagLoadIndex(&_rpmTags.byValue, &_rpmTags.byValueSize, tagCmpValue);
00107
00108 switch (tag) {
00109 case RPMDBI_PACKAGES:
00110 strcpy(nameBuf, "Packages");
00111 break;
00112 case RPMDBI_DEPENDS:
00113 strcpy(nameBuf, "Depends");
00114 break;
00115 case RPMDBI_ADDED:
00116 strcpy(nameBuf, "Added");
00117 break;
00118 case RPMDBI_REMOVED:
00119 strcpy(nameBuf, "Removed");
00120 break;
00121 case RPMDBI_AVAILABLE:
00122 strcpy(nameBuf, "Available");
00123 break;
00124 case RPMDBI_HDLIST:
00125 strcpy(nameBuf, "Hdlist");
00126 break;
00127 case RPMDBI_ARGLIST:
00128 strcpy(nameBuf, "Arglist");
00129 break;
00130 case RPMDBI_FTSWALK:
00131 strcpy(nameBuf, "Ftswalk");
00132 break;
00133
00134
00135 case RPMTAG_CONFLICTS:
00136 strcpy(nameBuf, "Conflictname");
00137 break;
00138 case RPMTAG_HDRID:
00139 strcpy(nameBuf, "Sha1header");
00140 break;
00141
00142 default:
00143 strcpy(nameBuf, "(unknown)");
00144 if (_rpmTags.byValue == NULL)
00145 break;
00146
00147 l = 0;
00148 u = _rpmTags.byValueSize;
00149 while (l < u) {
00150 i = (l + u) / 2;
00151 t = _rpmTags.byValue[i];
00152
00153 comparison = (tag - t->val);
00154
00155 if (comparison < 0)
00156 u = i;
00157 else if (comparison > 0)
00158 l = i + 1;
00159 else {
00160 nameBuf[0] = nameBuf[1] = '\0';
00161
00162 while (i > 0 && tag == _rpmTags.byValue[i-1]->val) {
00163 i--;
00164 t--;
00165 }
00166 t = _rpmTags.byValue[i];
00167 if (t->name != NULL)
00168 strcpy(nameBuf, t->name + (sizeof("RPMTAG_")-1));
00169 for (s = nameBuf+1; *s != '\0'; s++)
00170 *s = xtolower(*s);
00171 break;
00172 }
00173 }
00174 break;
00175 }
00176
00177 return nameBuf;
00178
00179 }
00180
00181 static int _tagType(int tag)
00182 {
00183 const struct headerTagTableEntry_s *t;
00184 int comparison, i, l, u;
00185 int xx;
00186
00187 if (_rpmTags.byValue == NULL)
00188 xx = tagLoadIndex(&_rpmTags.byValue, &_rpmTags.byValueSize, tagCmpValue);
00189
00190 switch (tag) {
00191 case RPMDBI_PACKAGES:
00192 case RPMDBI_DEPENDS:
00193 case RPMDBI_ADDED:
00194 case RPMDBI_REMOVED:
00195 case RPMDBI_AVAILABLE:
00196 case RPMDBI_HDLIST:
00197 case RPMDBI_ARGLIST:
00198 case RPMDBI_FTSWALK:
00199 break;
00200 default:
00201 if (_rpmTags.byValue == NULL)
00202 break;
00203
00204 l = 0;
00205 u = _rpmTags.byValueSize;
00206 while (l < u) {
00207 i = (l + u) / 2;
00208 t = _rpmTags.byValue[i];
00209
00210 comparison = (tag - t->val);
00211
00212 if (comparison < 0)
00213 u = i;
00214 else if (comparison > 0)
00215 l = i + 1;
00216 else {
00217
00218 while (i > 0 && t->val == _rpmTags.byValue[i-1]->val) {
00219 i--;
00220 t--;
00221 }
00222 return t->type;
00223 }
00224 }
00225 break;
00226 }
00227 return RPM_NULL_TYPE;
00228 }
00229
00230 static int _tagValue(const char * tagstr)
00231 {
00232 const struct headerTagTableEntry_s *t;
00233 int comparison, i, l, u;
00234 int xx;
00235
00236 if (!xstrcasecmp(tagstr, "Packages"))
00237 return RPMDBI_PACKAGES;
00238 if (!xstrcasecmp(tagstr, "Depends"))
00239 return RPMDBI_DEPENDS;
00240 if (!xstrcasecmp(tagstr, "Added"))
00241 return RPMDBI_ADDED;
00242 if (!xstrcasecmp(tagstr, "Removed"))
00243 return RPMDBI_REMOVED;
00244 if (!xstrcasecmp(tagstr, "Available"))
00245 return RPMDBI_AVAILABLE;
00246 if (!xstrcasecmp(tagstr, "Hdlist"))
00247 return RPMDBI_HDLIST;
00248 if (!xstrcasecmp(tagstr, "Arglist"))
00249 return RPMDBI_ARGLIST;
00250 if (!xstrcasecmp(tagstr, "Ftswalk"))
00251 return RPMDBI_FTSWALK;
00252
00253 if (_rpmTags.byName == NULL)
00254 xx = tagLoadIndex(&_rpmTags.byName, &_rpmTags.byNameSize, tagCmpName);
00255 if (_rpmTags.byName == NULL)
00256 return -1;
00257
00258 l = 0;
00259 u = _rpmTags.byNameSize;
00260 while (l < u) {
00261 i = (l + u) / 2;
00262 t = _rpmTags.byName[i];
00263
00264 comparison = xstrcasecmp(tagstr, t->name + (sizeof("RPMTAG_")-1));
00265
00266 if (comparison < 0)
00267 u = i;
00268 else if (comparison > 0)
00269 l = i + 1;
00270 else
00271 return t->val;
00272 }
00273 return -1;
00274 }