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 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, int_32 * type,
00179 const void ** data, int_32 * count,
00180 int * freeData)
00181
00182 {
00183 char ** array;
00184
00185 if (headerGetEntry(h, RPMTAG_INSTALLPREFIX, type, (void **)data, count)) {
00186 *freeData = 0;
00187 return 0;
00188 } else if (headerGetEntry(h, RPMTAG_INSTPREFIXES, NULL, (void **) &array,
00189 count)) {
00190 *data = xstrdup(array[0]);
00191 *freeData = 1;
00192 *type = RPM_STRING_TYPE;
00193 free(array);
00194 return 0;
00195 }
00196
00197 return 1;
00198 }
00199
00208 static int fssizesTag(Header h, int_32 * type,
00209 const void ** data, int_32 * count,
00210 int * freeData)
00211
00212 {
00213 const char ** filenames;
00214 int_32 * filesizes;
00215 uint_32 * usages;
00216 int numFiles;
00217
00218 if (!headerGetEntry(h, RPMTAG_FILESIZES, NULL, (void **) &filesizes,
00219 &numFiles)) {
00220 filesizes = NULL;
00221 numFiles = 0;
00222 filenames = NULL;
00223 } else {
00224 rpmBuildFileList(h, &filenames, &numFiles);
00225 }
00226
00227 if (rpmGetFilesystemList(NULL, count)) {
00228 return 1;
00229 }
00230
00231 *type = RPM_INT32_TYPE;
00232 *freeData = 1;
00233
00234 if (filenames == NULL) {
00235 usages = xcalloc((*count), sizeof(usages));
00236 *data = usages;
00237
00238 return 0;
00239 }
00240
00241 if (rpmGetFilesystemUsage(filenames, filesizes, numFiles, &usages, 0))
00242 return 1;
00243
00244 *data = usages;
00245
00246 if (filenames) free(filenames);
00247
00248 return 0;
00249 }
00250
00259 static int triggercondsTag(Header h, int_32 * type,
00260 const void ** data, int_32 * count,
00261 int * freeData)
00262
00263 {
00264 int_32 * indices, * flags;
00265 char ** names, ** versions;
00266 int numNames, numScripts;
00267 char ** conds, ** s;
00268 char * item, * flagsStr;
00269 char * chptr;
00270 int i, j;
00271 char buf[5];
00272
00273 if (!headerGetEntry(h, RPMTAG_TRIGGERNAME, NULL, (void **) &names,
00274 &numNames)) {
00275 *freeData = 0;
00276 return 0;
00277 }
00278
00279 headerGetEntry(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &indices, NULL);
00280 headerGetEntry(h, RPMTAG_TRIGGERFLAGS, NULL, (void **) &flags, NULL);
00281 headerGetEntry(h, RPMTAG_TRIGGERVERSION, NULL, (void **) &versions, NULL);
00282 headerGetEntry(h, RPMTAG_TRIGGERSCRIPTS, NULL, (void **) &s, &numScripts);
00283 free(s);
00284
00285 *freeData = 1;
00286 *data = conds = xmalloc(sizeof(char * ) * numScripts);
00287 *count = numScripts;
00288 *type = RPM_STRING_ARRAY_TYPE;
00289 for (i = 0; i < numScripts; i++) {
00290 chptr = xstrdup("");
00291
00292 for (j = 0; j < numNames; j++) {
00293 if (indices[j] != i) continue;
00294
00295 item = xmalloc(strlen(names[j]) + strlen(versions[j]) + 20);
00296 if (flags[j] & RPMSENSE_SENSEMASK) {
00297 buf[0] = '%', buf[1] = '\0';
00298 flagsStr = depflagsFormat(RPM_INT32_TYPE, flags, buf,
00299 0, j);
00300 sprintf(item, "%s %s %s", names[j], flagsStr, versions[j]);
00301 free(flagsStr);
00302 } else {
00303 strcpy(item, names[j]);
00304 }
00305
00306 chptr = xrealloc(chptr, strlen(chptr) + strlen(item) + 5);
00307 if (*chptr) strcat(chptr, ", ");
00308 strcat(chptr, item);
00309 free(item);
00310 }
00311
00312 conds[i] = chptr;
00313 }
00314
00315 free(names);
00316 free(versions);
00317
00318 return 0;
00319 }
00320
00329 static int triggertypeTag(Header h, int_32 * type,
00330 const void ** data, int_32 * count,
00331 int * freeData)
00332
00333 {
00334 int_32 * indices, * flags;
00335 char ** conds, ** s;
00336 int i, j;
00337 int numScripts, numNames;
00338
00339 if (!headerGetEntry(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &indices,
00340 &numNames)) {
00341 *freeData = 0;
00342 return 1;
00343 }
00344
00345 headerGetEntry(h, RPMTAG_TRIGGERFLAGS, NULL, (void **) &flags, NULL);
00346
00347 headerGetEntry(h, RPMTAG_TRIGGERSCRIPTS, NULL, (void **) &s, &numScripts);
00348 free(s);
00349
00350 *freeData = 1;
00351 *data = conds = xmalloc(sizeof(char * ) * numScripts);
00352 *count = numScripts;
00353 *type = RPM_STRING_ARRAY_TYPE;
00354 for (i = 0; i < numScripts; i++) {
00355 for (j = 0; j < numNames; j++) {
00356 if (indices[j] != i) continue;
00357
00358 if (flags[j] & RPMSENSE_TRIGGERIN)
00359 conds[i] = xstrdup("in");
00360 else if (flags[j] & RPMSENSE_TRIGGERUN)
00361 conds[i] = xstrdup("un");
00362 else
00363 conds[i] = xstrdup("postun");
00364 break;
00365 }
00366 }
00367
00368 return 0;
00369 }
00370
00379 static int filenamesTag(Header h, int_32 * type,
00380 const void ** data, int_32 * count,
00381 int * freeData)
00382
00383 {
00384 *type = RPM_STRING_ARRAY_TYPE;
00385
00386 rpmBuildFileList(h, (const char ***) data, count);
00387 *freeData = 1;
00388
00389 *freeData = 0;
00390
00391 return 0;
00392 }
00393
00394
00395
00396 int _nl_msg_cat_cntr;
00397 static const char * language = "LANGUAGE";
00398
00399 static char * _macro_i18ndomains = "%{?_i18ndomains:%{_i18ndomains}}";
00400
00410 static int i18nTag(Header h, int_32 tag, int_32 * type,
00411 const void ** data, int_32 * count,
00412 int * freeData)
00413
00414 {
00415 char * dstring = rpmExpand(_macro_i18ndomains, NULL);
00416 int rc;
00417
00418 *type = RPM_STRING_TYPE;
00419 *data = NULL;
00420 *count = 0;
00421 *freeData = 0;
00422
00423 if (dstring && *dstring) {
00424 char *domain, *de;
00425 const char * langval;
00426 const char * msgkey;
00427 const char * msgid;
00428
00429 { const char * tn = tagName(tag);
00430 const char * n;
00431 char * mk;
00432 headerNVR(h, &n, NULL, NULL);
00433 mk = alloca(strlen(n) + strlen(tn) + sizeof("()"));
00434 sprintf(mk, "%s(%s)", n, tn);
00435 msgkey = mk;
00436 }
00437
00438
00439 langval = getenv(language);
00440 setenv(language, "en_US", 1);
00441 ++_nl_msg_cat_cntr;
00442
00443 msgid = NULL;
00444 for (domain = dstring; domain != NULL; domain = de) {
00445 de = strchr(domain, ':');
00446 if (de) *de++ = '\0';
00447 msgid = dgettext(domain, msgkey) ;
00448 if (msgid != msgkey) break;
00449 }
00450
00451
00452 if (langval)
00453 setenv(language, langval, 1);
00454 else
00455 unsetenv(language);
00456 ++_nl_msg_cat_cntr;
00457
00458 if (domain && msgid) {
00459 *data = dgettext(domain, msgid) ;
00460 *data = xstrdup(*data);
00461 *count = 1;
00462 *freeData = 1;
00463 }
00464 free(dstring); dstring = NULL;
00465 if (*data) {
00466 return 0;
00467 }
00468 }
00469
00470 if (dstring) free(dstring);
00471
00472 rc = headerGetEntry(h, tag, type, (void **)data, count);
00473
00474 if (rc) {
00475 *data = xstrdup(*data);
00476 *freeData = 1;
00477 return 0;
00478 }
00479
00480 *freeData = 0;
00481 *data = NULL;
00482 *count = 0;
00483 return 1;
00484 }
00485
00494 static int summaryTag(Header h, int_32 * type,
00495 const void ** data, int_32 * count,
00496 int * freeData)
00497
00498 {
00499 return i18nTag(h, RPMTAG_SUMMARY, type, data, count, freeData);
00500 }
00501
00510 static int descriptionTag(Header h, int_32 * type,
00511 const void ** data, int_32 * count,
00512 int * freeData)
00513
00514 {
00515 return i18nTag(h, RPMTAG_DESCRIPTION, type, data, count, freeData);
00516 }
00517
00526 static int groupTag(Header h, int_32 * type,
00527 const void ** data, int_32 * count,
00528 int * freeData)
00529
00530 {
00531 return i18nTag(h, RPMTAG_GROUP, type, data, count, freeData);
00532 }
00533
00534 const struct headerSprintfExtension rpmHeaderFormats[] = {
00535 { HEADER_EXT_TAG, "RPMTAG_GROUP", { groupTag } },
00536 { HEADER_EXT_TAG, "RPMTAG_DESCRIPTION", { descriptionTag } },
00537 { HEADER_EXT_TAG, "RPMTAG_SUMMARY", { summaryTag } },
00538 { HEADER_EXT_TAG, "RPMTAG_FILENAMES", { filenamesTag } },
00539 { HEADER_EXT_TAG, "RPMTAG_FSSIZES", { fssizesTag } },
00540 { HEADER_EXT_TAG, "RPMTAG_FSNAMES", { fsnamesTag } },
00541 { HEADER_EXT_TAG, "RPMTAG_INSTALLPREFIX", { instprefixTag } },
00542 { HEADER_EXT_TAG, "RPMTAG_TRIGGERCONDS", { triggercondsTag } },
00543 { HEADER_EXT_TAG, "RPMTAG_TRIGGERTYPE", { triggertypeTag } },
00544 { HEADER_EXT_FORMAT, "depflags", { depflagsFormat } },
00545 { HEADER_EXT_FORMAT, "fflags", { fflagsFormat } },
00546 { HEADER_EXT_FORMAT, "perms", { permsFormat } },
00547 { HEADER_EXT_FORMAT, "permissions", { permsFormat } },
00548 { HEADER_EXT_FORMAT, "triggertype", { triggertypeFormat } },
00549 { HEADER_EXT_MORE, NULL, { (void *) headerDefaultFormats } }
00550 } ;