00001
00005 #include "system.h"
00006 #include <rpmlib.h>
00007 #include <rpmmacro.h>
00008 #include "manifest.h"
00009 #include "misc.h"
00010 #include "debug.h"
00011
00020 static char * triggertypeFormat(int_32 type, const void * data,
00021 char * formatPrefix, int padding,
00022 int element)
00023 {
00024 const int_32 * item = data;
00025 char * val;
00026
00027 if (type != RPM_INT32_TYPE) {
00028 val = xstrdup(_("(not a number)"));
00029 } else if (*item & RPMSENSE_TRIGGERIN) {
00030 val = xstrdup("in");
00031 } else {
00032 val = xstrdup("un");
00033 }
00034
00035 return val;
00036 }
00037
00046 static char * permsFormat(int_32 type, const void * data, char * formatPrefix,
00047 int padding, int element)
00048
00049 {
00050 char * val;
00051 char * buf;
00052
00053 if (type != RPM_INT32_TYPE) {
00054 val = xstrdup(_("(not a number)"));
00055 } else {
00056 val = xmalloc(15 + padding);
00057 strcat(formatPrefix, "s");
00058 buf = rpmPermsString(*((int_32 *) data));
00059 sprintf(val, formatPrefix, buf);
00060 buf = _free(buf);
00061 }
00062
00063 return val;
00064 }
00065
00074 static char * fflagsFormat(int_32 type, const void * data,
00075 char * formatPrefix, int padding, int element)
00076
00077 {
00078 char * val;
00079 char buf[15];
00080 int anint = *((int_32 *) data);
00081
00082 if (type != RPM_INT32_TYPE) {
00083 val = xstrdup(_("(not a number)"));
00084 } else {
00085 buf[0] = '\0';
00086 if (anint & RPMFILE_DOC)
00087 strcat(buf, "d");
00088 if (anint & RPMFILE_CONFIG)
00089 strcat(buf, "c");
00090 if (anint & RPMFILE_SPECFILE)
00091 strcat(buf, "s");
00092 if (anint & RPMFILE_MISSINGOK)
00093 strcat(buf, "m");
00094 if (anint & RPMFILE_NOREPLACE)
00095 strcat(buf, "n");
00096 if (anint & RPMFILE_GHOST)
00097 strcat(buf, "g");
00098
00099 val = xmalloc(5 + padding);
00100 strcat(formatPrefix, "s");
00101 sprintf(val, formatPrefix, buf);
00102 }
00103
00104 return val;
00105 }
00106
00115 static char * depflagsFormat(int_32 type, const void * data,
00116 char * formatPrefix, int padding, int element)
00117
00118 {
00119 char * val;
00120 char buf[10];
00121 int anint = *((int_32 *) data);
00122
00123 if (type != RPM_INT32_TYPE) {
00124 val = xstrdup(_("(not a number)"));
00125 } else {
00126 buf[0] = '\0';
00127
00128 if (anint & RPMSENSE_LESS)
00129 strcat(buf, "<");
00130 if (anint & RPMSENSE_GREATER)
00131 strcat(buf, ">");
00132 if (anint & RPMSENSE_EQUAL)
00133 strcat(buf, "=");
00134
00135 val = xmalloc(5 + padding);
00136 strcat(formatPrefix, "s");
00137 sprintf(val, formatPrefix, buf);
00138 }
00139
00140 return val;
00141 }
00142
00151 static int fsnamesTag( Header h, int_32 * type,
00152 void ** data, int_32 * count,
00153 int * freeData)
00154
00155 {
00156 const char ** list;
00157
00158 if (rpmGetFilesystemList(&list, count)) {
00159 return 1;
00160 }
00161
00162 *type = RPM_STRING_ARRAY_TYPE;
00163 *((const char ***) data) = list;
00164
00165 *freeData = 0;
00166
00167 return 0;
00168 }
00169
00178 static int instprefixTag(Header h, rpmTagType * type,
00179 const void ** data,
00180 int_32 * count,
00181 int * freeData)
00182
00183 {
00184 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00185 HFD_t hfd = headerFreeData;
00186 rpmTagType ipt;
00187 char ** array;
00188
00189 if (hge(h, RPMTAG_INSTALLPREFIX, type, (void **)data, count)) {
00190 if (freeData) *freeData = 0;
00191 return 0;
00192 } else if (hge(h, RPMTAG_INSTPREFIXES, &ipt, (void **) &array, count)) {
00193 if (data) *data = xstrdup(array[0]);
00194 if (freeData) *freeData = 1;
00195 if (type) *type = RPM_STRING_TYPE;
00196 array = hfd(array, ipt);
00197 return 0;
00198 }
00199
00200 return 1;
00201 }
00202
00211 static int fssizesTag(Header h, rpmTagType * type,
00212 const void ** data, int_32 * count,
00213 int * freeData)
00214
00215 {
00216 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00217 const char ** filenames;
00218 int_32 * filesizes;
00219 uint_32 * usages;
00220 int numFiles;
00221
00222 if (!hge(h, RPMTAG_FILESIZES, NULL, (void **) &filesizes, &numFiles)) {
00223 filesizes = NULL;
00224 numFiles = 0;
00225 filenames = NULL;
00226 } else {
00227 rpmBuildFileList(h, &filenames, &numFiles);
00228 }
00229
00230 if (rpmGetFilesystemList(NULL, count)) {
00231 return 1;
00232 }
00233
00234 *type = RPM_INT32_TYPE;
00235 *freeData = 1;
00236
00237 if (filenames == NULL) {
00238 usages = xcalloc((*count), sizeof(usages));
00239 *data = usages;
00240
00241 return 0;
00242 }
00243
00244 if (rpmGetFilesystemUsage(filenames, filesizes, numFiles, &usages, 0))
00245 return 1;
00246
00247 *data = usages;
00248
00249 filenames = _free(filenames);
00250
00251 return 0;
00252 }
00253
00262 static int triggercondsTag(Header h, rpmTagType * type,
00263 const void ** data, int_32 * count,
00264 int * freeData)
00265
00266 {
00267 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00268 HFD_t hfd = headerFreeData;
00269 rpmTagType tnt, tvt, tst;
00270 int_32 * indices, * flags;
00271 char ** names, ** versions;
00272 int numNames, numScripts;
00273 char ** conds, ** s;
00274 char * item, * flagsStr;
00275 char * chptr;
00276 int i, j;
00277 char buf[5];
00278
00279 if (!hge(h, RPMTAG_TRIGGERNAME, &tnt, (void **) &names, &numNames)) {
00280 *freeData = 0;
00281 return 0;
00282 }
00283
00284 (void) hge(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &indices, NULL);
00285 (void) hge(h, RPMTAG_TRIGGERFLAGS, NULL, (void **) &flags, NULL);
00286 (void) hge(h, RPMTAG_TRIGGERVERSION, &tvt, (void **) &versions, NULL);
00287 (void) hge(h, RPMTAG_TRIGGERSCRIPTS, &tst, (void **) &s, &numScripts);
00288 s = hfd(s, tst);
00289
00290 *freeData = 1;
00291 *data = conds = xmalloc(sizeof(char * ) * numScripts);
00292 *count = numScripts;
00293 *type = RPM_STRING_ARRAY_TYPE;
00294 for (i = 0; i < numScripts; i++) {
00295 chptr = xstrdup("");
00296
00297 for (j = 0; j < numNames; j++) {
00298 if (indices[j] != i) continue;
00299
00300 item = xmalloc(strlen(names[j]) + strlen(versions[j]) + 20);
00301 if (flags[j] & RPMSENSE_SENSEMASK) {
00302 buf[0] = '%', buf[1] = '\0';
00303 flagsStr = depflagsFormat(RPM_INT32_TYPE, flags, buf, 0, j);
00304 sprintf(item, "%s %s %s", names[j], flagsStr, versions[j]);
00305 flagsStr = _free(flagsStr);
00306 } else {
00307 strcpy(item, names[j]);
00308 }
00309
00310 chptr = xrealloc(chptr, strlen(chptr) + strlen(item) + 5);
00311 if (*chptr != '\0') strcat(chptr, ", ");
00312 strcat(chptr, item);
00313 item = _free(item);
00314 }
00315
00316 conds[i] = chptr;
00317 }
00318
00319 names = hfd(names, tnt);
00320 versions = hfd(versions, tvt);
00321
00322 return 0;
00323 }
00324
00333 static int triggertypeTag(Header h, rpmTagType * type,
00334 const void ** data, int_32 * count,
00335 int * freeData)
00336
00337 {
00338 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00339 HFD_t hfd = headerFreeData;
00340 rpmTagType tst;
00341 int_32 * indices, * flags;
00342 const char ** conds;
00343 const char ** s;
00344 int i, j;
00345 int numScripts, numNames;
00346
00347 if (!hge(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &indices, &numNames)) {
00348 *freeData = 0;
00349 return 1;
00350 }
00351
00352 (void) hge(h, RPMTAG_TRIGGERFLAGS, NULL, (void **) &flags, NULL);
00353 (void) hge(h, RPMTAG_TRIGGERSCRIPTS, &tst, (void **) &s, &numScripts);
00354 s = hfd(s, tst);
00355
00356 *freeData = 1;
00357 *data = conds = xmalloc(sizeof(char * ) * numScripts);
00358 *count = numScripts;
00359 *type = RPM_STRING_ARRAY_TYPE;
00360 for (i = 0; i < numScripts; i++) {
00361 for (j = 0; j < numNames; j++) {
00362 if (indices[j] != i) continue;
00363
00364 if (flags[j] & RPMSENSE_TRIGGERIN)
00365 conds[i] = xstrdup("in");
00366 else if (flags[j] & RPMSENSE_TRIGGERUN)
00367 conds[i] = xstrdup("un");
00368 else
00369 conds[i] = xstrdup("postun");
00370 break;
00371 }
00372 }
00373
00374 return 0;
00375 }
00376
00385 static int filenamesTag(Header h, rpmTagType * type,
00386 const void ** data, int_32 * count,
00387 int * freeData)
00388
00389 {
00390 *type = RPM_STRING_ARRAY_TYPE;
00391
00392 rpmBuildFileList(h, (const char ***) data, count);
00393 *freeData = 1;
00394
00395 *freeData = 0;
00396
00397 return 0;
00398 }
00399
00400
00401
00402
00403 int _nl_msg_cat_cntr;
00404
00405 static const char * language = "LANGUAGE";
00406
00407 static const char * _macro_i18ndomains =
00408 "%{?_i18ndomains:%{_i18ndomains}}";
00409
00419 static int i18nTag(Header h, int_32 tag, rpmTagType * type,
00420 const void ** data, int_32 * count,
00421 int * freeData)
00422
00423 {
00424 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00425 char * dstring = rpmExpand(_macro_i18ndomains, NULL);
00426 int rc;
00427
00428 *type = RPM_STRING_TYPE;
00429 *data = NULL;
00430 *count = 0;
00431 *freeData = 0;
00432
00433 if (dstring && *dstring) {
00434 char *domain, *de;
00435 const char * langval;
00436 const char * msgkey;
00437 const char * msgid;
00438
00439 { const char * tn = tagName(tag);
00440 const char * n;
00441 char * mk;
00442 (void) headerNVR(h, &n, NULL, NULL);
00443 mk = alloca(strlen(n) + strlen(tn) + sizeof("()"));
00444 sprintf(mk, "%s(%s)", n, tn);
00445 msgkey = mk;
00446 }
00447
00448
00449 langval = getenv(language);
00450 (void) setenv(language, "en_US", 1);
00451 ++_nl_msg_cat_cntr;
00452
00453 msgid = NULL;
00454 for (domain = dstring; domain != NULL; domain = de) {
00455 de = strchr(domain, ':');
00456 if (de) *de++ = '\0';
00457 msgid = dgettext(domain, msgkey) ;
00458 if (msgid != msgkey) break;
00459 }
00460
00461
00462 if (langval)
00463 (void) setenv(language, langval, 1);
00464 else
00465 unsetenv(language);
00466 ++_nl_msg_cat_cntr;
00467
00468 if (domain && msgid) {
00469 *data = dgettext(domain, msgid) ;
00470 *data = xstrdup(*data);
00471 *count = 1;
00472 *freeData = 1;
00473 }
00474 dstring = _free(dstring);
00475 if (*data)
00476 return 0;
00477 }
00478
00479 dstring = _free(dstring);
00480
00481 rc = hge(h, tag, type, (void **)data, count);
00482
00483 if (rc) {
00484 *data = xstrdup(*data);
00485 *freeData = 1;
00486 return 0;
00487 }
00488
00489 *freeData = 0;
00490 *data = NULL;
00491 *count = 0;
00492 return 1;
00493 }
00494
00503 static int summaryTag(Header h, rpmTagType * type,
00504 const void ** data, int_32 * count,
00505 int * freeData)
00506
00507 {
00508 return i18nTag(h, RPMTAG_SUMMARY, type, data, count, freeData);
00509 }
00510
00519 static int descriptionTag(Header h, rpmTagType * type,
00520 const void ** data, int_32 * count,
00521 int * freeData)
00522
00523 {
00524 return i18nTag(h, RPMTAG_DESCRIPTION, type, data, count, freeData);
00525 }
00526
00535 static int groupTag(Header h, rpmTagType * type,
00536 const void ** data, int_32 * count,
00537 int * freeData)
00538
00539 {
00540 return i18nTag(h, RPMTAG_GROUP, type, data, count, freeData);
00541 }
00542
00543 const struct headerSprintfExtension_s rpmHeaderFormats[] = {
00544 { HEADER_EXT_TAG, "RPMTAG_GROUP", { groupTag } },
00545 { HEADER_EXT_TAG, "RPMTAG_DESCRIPTION", { descriptionTag } },
00546 { HEADER_EXT_TAG, "RPMTAG_SUMMARY", { summaryTag } },
00547 { HEADER_EXT_TAG, "RPMTAG_FILENAMES", { filenamesTag } },
00548 { HEADER_EXT_TAG, "RPMTAG_FSSIZES", { fssizesTag } },
00549 { HEADER_EXT_TAG, "RPMTAG_FSNAMES", { fsnamesTag } },
00550 { HEADER_EXT_TAG, "RPMTAG_INSTALLPREFIX", { instprefixTag } },
00551 { HEADER_EXT_TAG, "RPMTAG_TRIGGERCONDS", { triggercondsTag } },
00552 { HEADER_EXT_TAG, "RPMTAG_TRIGGERTYPE", { triggertypeTag } },
00553 { HEADER_EXT_FORMAT, "depflags", { depflagsFormat } },
00554 { HEADER_EXT_FORMAT, "fflags", { fflagsFormat } },
00555 { HEADER_EXT_FORMAT, "perms", { permsFormat } },
00556 { HEADER_EXT_FORMAT, "permissions", { permsFormat } },
00557 { HEADER_EXT_FORMAT, "triggertype", { triggertypeFormat } },
00558 { HEADER_EXT_MORE, NULL, { (void *) headerDefaultFormats } }
00559 } ;