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
00060 sprintf(val, formatPrefix, buf);
00061
00062 buf = _free(buf);
00063 }
00064
00065 return val;
00066 }
00067
00076 static char * fflagsFormat(int_32 type, const void * data,
00077 char * formatPrefix, int padding, int element)
00078
00079 {
00080 char * val;
00081 char buf[15];
00082 int anint = *((int_32 *) data);
00083
00084 if (type != RPM_INT32_TYPE) {
00085 val = xstrdup(_("(not a number)"));
00086 } else {
00087 buf[0] = '\0';
00088 if (anint & RPMFILE_DOC)
00089 strcat(buf, "d");
00090 if (anint & RPMFILE_CONFIG)
00091 strcat(buf, "c");
00092 if (anint & RPMFILE_SPECFILE)
00093 strcat(buf, "s");
00094 if (anint & RPMFILE_MISSINGOK)
00095 strcat(buf, "m");
00096 if (anint & RPMFILE_NOREPLACE)
00097 strcat(buf, "n");
00098 if (anint & RPMFILE_GHOST)
00099 strcat(buf, "g");
00100
00101 val = xmalloc(5 + padding);
00102 strcat(formatPrefix, "s");
00103
00104 sprintf(val, formatPrefix, buf);
00105
00106 }
00107
00108 return val;
00109 }
00110
00119 static char * depflagsFormat(int_32 type, const void * data,
00120 char * formatPrefix, int padding, int element)
00121
00122 {
00123 char * val;
00124 char buf[10];
00125 int anint = *((int_32 *) data);
00126
00127 if (type != RPM_INT32_TYPE) {
00128 val = xstrdup(_("(not a number)"));
00129 } else {
00130 buf[0] = '\0';
00131
00132 if (anint & RPMSENSE_LESS)
00133 strcat(buf, "<");
00134 if (anint & RPMSENSE_GREATER)
00135 strcat(buf, ">");
00136 if (anint & RPMSENSE_EQUAL)
00137 strcat(buf, "=");
00138
00139 val = xmalloc(5 + padding);
00140 strcat(formatPrefix, "s");
00141
00142 sprintf(val, formatPrefix, buf);
00143
00144 }
00145
00146 return val;
00147 }
00148
00157 static int fsnamesTag( Header h, int_32 * type,
00158 void ** data, int_32 * count,
00159 int * freeData)
00160
00161 {
00162 const char ** list;
00163
00164 if (rpmGetFilesystemList(&list, count)) {
00165 return 1;
00166 }
00167
00168 *type = RPM_STRING_ARRAY_TYPE;
00169 *((const char ***) data) = list;
00170
00171 *freeData = 0;
00172
00173 return 0;
00174 }
00175
00184 static int instprefixTag(Header h, rpmTagType * type,
00185 const void ** data,
00186 int_32 * count,
00187 int * freeData)
00188
00189 {
00190 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00191 HFD_t hfd = headerFreeData;
00192 rpmTagType ipt;
00193 char ** array;
00194
00195 if (hge(h, RPMTAG_INSTALLPREFIX, type, (void **)data, count)) {
00196 if (freeData) *freeData = 0;
00197 return 0;
00198 } else if (hge(h, RPMTAG_INSTPREFIXES, &ipt, (void **) &array, count)) {
00199 if (data) *data = xstrdup(array[0]);
00200 if (freeData) *freeData = 1;
00201 if (type) *type = RPM_STRING_TYPE;
00202 array = hfd(array, ipt);
00203 return 0;
00204 }
00205
00206 return 1;
00207 }
00208
00217 static int fssizesTag(Header h, rpmTagType * type,
00218 const void ** data, int_32 * count,
00219 int * freeData)
00220
00221 {
00222 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00223 const char ** filenames;
00224 int_32 * filesizes;
00225 uint_32 * usages;
00226 int numFiles;
00227
00228 if (!hge(h, RPMTAG_FILESIZES, NULL, (void **) &filesizes, &numFiles)) {
00229 filesizes = NULL;
00230 numFiles = 0;
00231 filenames = NULL;
00232 } else {
00233 rpmBuildFileList(h, &filenames, &numFiles);
00234 }
00235
00236 if (rpmGetFilesystemList(NULL, count)) {
00237 return 1;
00238 }
00239
00240 *type = RPM_INT32_TYPE;
00241 *freeData = 1;
00242
00243 if (filenames == NULL) {
00244 usages = xcalloc((*count), sizeof(usages));
00245 *data = usages;
00246
00247 return 0;
00248 }
00249
00250 if (rpmGetFilesystemUsage(filenames, filesizes, numFiles, &usages, 0))
00251 return 1;
00252
00253 *data = usages;
00254
00255 filenames = _free(filenames);
00256
00257 return 0;
00258 }
00259
00268 static int triggercondsTag(Header h, rpmTagType * type,
00269 const void ** data, int_32 * count,
00270 int * freeData)
00271
00272 {
00273 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00274 HFD_t hfd = headerFreeData;
00275 rpmTagType tnt, tvt, tst;
00276 int_32 * indices, * flags;
00277 char ** names, ** versions;
00278 int numNames, numScripts;
00279 char ** conds, ** s;
00280 char * item, * flagsStr;
00281 char * chptr;
00282 int i, j;
00283 char buf[5];
00284
00285 if (!hge(h, RPMTAG_TRIGGERNAME, &tnt, (void **) &names, &numNames)) {
00286 *freeData = 0;
00287 return 0;
00288 }
00289
00290 (void) hge(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &indices, NULL);
00291 (void) hge(h, RPMTAG_TRIGGERFLAGS, NULL, (void **) &flags, NULL);
00292 (void) hge(h, RPMTAG_TRIGGERVERSION, &tvt, (void **) &versions, NULL);
00293 (void) hge(h, RPMTAG_TRIGGERSCRIPTS, &tst, (void **) &s, &numScripts);
00294 s = hfd(s, tst);
00295
00296 *freeData = 1;
00297 *data = conds = xmalloc(sizeof(char * ) * numScripts);
00298 *count = numScripts;
00299 *type = RPM_STRING_ARRAY_TYPE;
00300 for (i = 0; i < numScripts; i++) {
00301 chptr = xstrdup("");
00302
00303 for (j = 0; j < numNames; j++) {
00304 if (indices[j] != i) continue;
00305
00306 item = xmalloc(strlen(names[j]) + strlen(versions[j]) + 20);
00307 if (flags[j] & RPMSENSE_SENSEMASK) {
00308 buf[0] = '%', buf[1] = '\0';
00309 flagsStr = depflagsFormat(RPM_INT32_TYPE, flags, buf, 0, j);
00310 sprintf(item, "%s %s %s", names[j], flagsStr, versions[j]);
00311 flagsStr = _free(flagsStr);
00312 } else {
00313 strcpy(item, names[j]);
00314 }
00315
00316 chptr = xrealloc(chptr, strlen(chptr) + strlen(item) + 5);
00317 if (*chptr != '\0') strcat(chptr, ", ");
00318 strcat(chptr, item);
00319 item = _free(item);
00320 }
00321
00322 conds[i] = chptr;
00323 }
00324
00325 names = hfd(names, tnt);
00326 versions = hfd(versions, tvt);
00327
00328 return 0;
00329 }
00330
00339 static int triggertypeTag(Header h, rpmTagType * type,
00340 const void ** data, int_32 * count,
00341 int * freeData)
00342
00343 {
00344 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00345 HFD_t hfd = headerFreeData;
00346 rpmTagType tst;
00347 int_32 * indices, * flags;
00348 const char ** conds;
00349 const char ** s;
00350 int i, j;
00351 int numScripts, numNames;
00352
00353 if (!hge(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &indices, &numNames)) {
00354 *freeData = 0;
00355 return 1;
00356 }
00357
00358 (void) hge(h, RPMTAG_TRIGGERFLAGS, NULL, (void **) &flags, NULL);
00359 (void) hge(h, RPMTAG_TRIGGERSCRIPTS, &tst, (void **) &s, &numScripts);
00360 s = hfd(s, tst);
00361
00362 *freeData = 1;
00363 *data = conds = xmalloc(sizeof(char * ) * numScripts);
00364 *count = numScripts;
00365 *type = RPM_STRING_ARRAY_TYPE;
00366 for (i = 0; i < numScripts; i++) {
00367 for (j = 0; j < numNames; j++) {
00368 if (indices[j] != i) continue;
00369
00370 if (flags[j] & RPMSENSE_TRIGGERIN)
00371 conds[i] = xstrdup("in");
00372 else if (flags[j] & RPMSENSE_TRIGGERUN)
00373 conds[i] = xstrdup("un");
00374 else
00375 conds[i] = xstrdup("postun");
00376 break;
00377 }
00378 }
00379
00380 return 0;
00381 }
00382
00391 static int filenamesTag(Header h, rpmTagType * type,
00392 const void ** data, int_32 * count,
00393 int * freeData)
00394
00395 {
00396 *type = RPM_STRING_ARRAY_TYPE;
00397
00398 rpmBuildFileList(h, (const char ***) data, count);
00399 *freeData = 1;
00400
00401 *freeData = 0;
00402
00403 return 0;
00404 }
00405
00406
00407
00408
00409 int _nl_msg_cat_cntr;
00410
00411 static const char * language = "LANGUAGE";
00412
00413 static const char * _macro_i18ndomains =
00414 "%{?_i18ndomains:%{_i18ndomains}}";
00415
00425 static int i18nTag(Header h, int_32 tag, rpmTagType * type,
00426 const void ** data, int_32 * count,
00427 int * freeData)
00428
00429 {
00430 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00431 char * dstring = rpmExpand(_macro_i18ndomains, NULL);
00432 int rc;
00433
00434 *type = RPM_STRING_TYPE;
00435 *data = NULL;
00436 *count = 0;
00437 *freeData = 0;
00438
00439 if (dstring && *dstring) {
00440 char *domain, *de;
00441 const char * langval;
00442 const char * msgkey;
00443 const char * msgid;
00444
00445 { const char * tn = tagName(tag);
00446 const char * n;
00447 char * mk;
00448 (void) headerNVR(h, &n, NULL, NULL);
00449 mk = alloca(strlen(n) + strlen(tn) + sizeof("()"));
00450 sprintf(mk, "%s(%s)", n, tn);
00451 msgkey = mk;
00452 }
00453
00454
00455 langval = getenv(language);
00456 (void) setenv(language, "en_US", 1);
00457 ++_nl_msg_cat_cntr;
00458
00459 msgid = NULL;
00460 for (domain = dstring; domain != NULL; domain = de) {
00461 de = strchr(domain, ':');
00462 if (de) *de++ = '\0';
00463 msgid = dgettext(domain, msgkey) ;
00464 if (msgid != msgkey) break;
00465 }
00466
00467
00468 if (langval)
00469 (void) setenv(language, langval, 1);
00470 else
00471 unsetenv(language);
00472 ++_nl_msg_cat_cntr;
00473
00474 if (domain && msgid) {
00475 *data = dgettext(domain, msgid) ;
00476 *data = xstrdup(*data);
00477 *count = 1;
00478 *freeData = 1;
00479 }
00480 dstring = _free(dstring);
00481 if (*data)
00482 return 0;
00483 }
00484
00485 dstring = _free(dstring);
00486
00487 rc = hge(h, tag, type, (void **)data, count);
00488
00489 if (rc && (*data) != NULL) {
00490 *data = xstrdup(*data);
00491 *freeData = 1;
00492 return 0;
00493 }
00494
00495 *freeData = 0;
00496 *data = NULL;
00497 *count = 0;
00498 return 1;
00499 }
00500
00509 static int summaryTag(Header h, rpmTagType * type,
00510 const void ** data, int_32 * count,
00511 int * freeData)
00512
00513 {
00514 return i18nTag(h, RPMTAG_SUMMARY, type, data, count, freeData);
00515 }
00516
00525 static int descriptionTag(Header h, rpmTagType * type,
00526 const void ** data, int_32 * count,
00527 int * freeData)
00528
00529 {
00530 return i18nTag(h, RPMTAG_DESCRIPTION, type, data, count, freeData);
00531 }
00532
00541 static int groupTag(Header h, rpmTagType * type,
00542 const void ** data, int_32 * count,
00543 int * freeData)
00544
00545 {
00546 return i18nTag(h, RPMTAG_GROUP, type, data, count, freeData);
00547 }
00548
00549 const struct headerSprintfExtension_s rpmHeaderFormats[] = {
00550 { HEADER_EXT_TAG, "RPMTAG_GROUP", { groupTag } },
00551 { HEADER_EXT_TAG, "RPMTAG_DESCRIPTION", { descriptionTag } },
00552 { HEADER_EXT_TAG, "RPMTAG_SUMMARY", { summaryTag } },
00553 { HEADER_EXT_TAG, "RPMTAG_FILENAMES", { filenamesTag } },
00554 { HEADER_EXT_TAG, "RPMTAG_FSSIZES", { fssizesTag } },
00555 { HEADER_EXT_TAG, "RPMTAG_FSNAMES", { fsnamesTag } },
00556 { HEADER_EXT_TAG, "RPMTAG_INSTALLPREFIX", { instprefixTag } },
00557 { HEADER_EXT_TAG, "RPMTAG_TRIGGERCONDS", { triggercondsTag } },
00558 { HEADER_EXT_TAG, "RPMTAG_TRIGGERTYPE", { triggertypeTag } },
00559 { HEADER_EXT_FORMAT, "depflags", { depflagsFormat } },
00560 { HEADER_EXT_FORMAT, "fflags", { fflagsFormat } },
00561 { HEADER_EXT_FORMAT, "perms", { permsFormat } },
00562 { HEADER_EXT_FORMAT, "permissions", { permsFormat } },
00563 { HEADER_EXT_FORMAT, "triggertype", { triggertypeFormat } },
00564 { HEADER_EXT_MORE, NULL, { (void *) headerDefaultFormats } }
00565 } ;