00001
00005 #include "system.h"
00006 #include <rpmlib.h>
00007 #include <rpmmacro.h>
00008 #include "rpmpgp.h"
00009 #include "manifest.h"
00010 #include "misc.h"
00011 #include "debug.h"
00012
00021 static char * triggertypeFormat(int_32 type, const void * data,
00022 char * formatPrefix, int padding,
00023 int element)
00024 {
00025 const int_32 * item = data;
00026 char * val;
00027
00028 if (type != RPM_INT32_TYPE)
00029 val = xstrdup(_("(not a number)"));
00030 else if (*item & RPMSENSE_TRIGGERIN)
00031 val = xstrdup("in");
00032 else
00033 val = xstrdup("un");
00034 return val;
00035 }
00036
00045 static char * permsFormat(int_32 type, const void * data, char * formatPrefix,
00046 int padding, int element)
00047
00048 {
00049 char * val;
00050 char * buf;
00051
00052 if (type != RPM_INT32_TYPE) {
00053 val = xstrdup(_("(not a number)"));
00054 } else {
00055 val = xmalloc(15 + padding);
00056 strcat(formatPrefix, "s");
00057 buf = rpmPermsString(*((int_32 *) data));
00058
00059 sprintf(val, formatPrefix, buf);
00060
00061 buf = _free(buf);
00062 }
00063
00064 return val;
00065 }
00066
00075 static char * fflagsFormat(int_32 type, const void * data,
00076 char * formatPrefix, int padding, int element)
00077
00078 {
00079 char * val;
00080 char buf[15];
00081 int anint = *((int_32 *) data);
00082
00083 if (type != RPM_INT32_TYPE) {
00084 val = xstrdup(_("(not a number)"));
00085 } else {
00086 buf[0] = '\0';
00087 if (anint & RPMFILE_DOC)
00088 strcat(buf, "d");
00089 if (anint & RPMFILE_CONFIG)
00090 strcat(buf, "c");
00091 if (anint & RPMFILE_SPECFILE)
00092 strcat(buf, "s");
00093 if (anint & RPMFILE_MISSINGOK)
00094 strcat(buf, "m");
00095 if (anint & RPMFILE_NOREPLACE)
00096 strcat(buf, "n");
00097 if (anint & RPMFILE_GHOST)
00098 strcat(buf, "g");
00099
00100 val = xmalloc(5 + padding);
00101 strcat(formatPrefix, "s");
00102
00103 sprintf(val, formatPrefix, buf);
00104
00105 }
00106
00107 return val;
00108 }
00109
00118 static char * armorFormat(int_32 type, const void * data,
00119 char * formatPrefix, int padding, int element)
00120
00121 {
00122 const char * enc;
00123 const char * s;
00124 char * t;
00125 char * val;
00126 int atype;
00127 int lc, ns, nt;
00128
00129 switch (type) {
00130 case RPM_BIN_TYPE:
00131 s = data;
00132 ns = element;
00133 atype = PGPARMOR_SIGNATURE;
00134 break;
00135 case RPM_STRING_TYPE:
00136 case RPM_STRING_ARRAY_TYPE:
00137 enc = data;
00138 if (b64decode(enc, (void **)&s, &ns))
00139 return xstrdup(_("(not base64)"));
00140 atype = PGPARMOR_PUBKEY;
00141 break;
00142 case RPM_NULL_TYPE:
00143 case RPM_CHAR_TYPE:
00144 case RPM_INT8_TYPE:
00145 case RPM_INT16_TYPE:
00146 case RPM_INT32_TYPE:
00147 case RPM_I18NSTRING_TYPE:
00148 default:
00149 return xstrdup(_("(invalid type)"));
00150 break;
00151 }
00152
00153 nt = ((ns + 2) / 3) * 4;
00154
00155
00156 if (b64encode_chars_per_line > 0 && b64encode_eolstr != NULL) {
00157 lc = (nt + b64encode_chars_per_line - 1) / b64encode_chars_per_line;
00158 if (((nt + b64encode_chars_per_line - 1) % b64encode_chars_per_line) != 0)
00159 ++lc;
00160 nt += lc * strlen(b64encode_eolstr);
00161 }
00162
00163
00164 nt += 512;
00165
00166 val = t = xmalloc(nt + padding + 1);
00167 *t = '\0';
00168 t = stpcpy(t, "-----BEGIN PGP ");
00169 t = stpcpy(t, pgpValStr(pgpArmorTbl, atype));
00170
00171 t = stpcpy( stpcpy(t, "-----\nVersion: rpm-"), RPMVERSION);
00172
00173 t = stpcpy(t, " (beecrypt-2.2.0)\n\n");
00174
00175 if ((enc = b64encode(s, ns)) != NULL) {
00176 t = stpcpy(t, enc);
00177 enc = _free(enc);
00178 if ((enc = b64crc(s, ns)) != NULL) {
00179 *t++ = '=';
00180 t = stpcpy(t, enc);
00181 enc = _free(enc);
00182 }
00183 }
00184
00185 t = stpcpy(t, "-----END PGP ");
00186 t = stpcpy(t, pgpValStr(pgpArmorTbl, atype));
00187 t = stpcpy(t, "-----\n");
00188
00189
00190 if (s != data) s = _free(s);
00191
00192
00193 return val;
00194 }
00195
00204 static char * base64Format(int_32 type, const void * data,
00205 char * formatPrefix, int padding, int element)
00206
00207 {
00208 char * val;
00209
00210 if (type != RPM_BIN_TYPE) {
00211 val = xstrdup(_("(not a blob)"));
00212 } else {
00213 const char * enc;
00214 char * t;
00215 int lc;
00216 int nt = ((element + 2) / 3) * 4;
00217
00218
00219
00220 if (b64encode_chars_per_line > 0 && b64encode_eolstr != NULL) {
00221 lc = (nt + b64encode_chars_per_line - 1) / b64encode_chars_per_line;
00222 if (((nt + b64encode_chars_per_line - 1) % b64encode_chars_per_line) != 0)
00223 ++lc;
00224 nt += lc * strlen(b64encode_eolstr);
00225 }
00226
00227
00228 val = t = xmalloc(nt + padding + 1);
00229
00230 *t = '\0';
00231 if ((enc = b64encode(data, element)) != NULL) {
00232 t = stpcpy(t, enc);
00233 enc = _free(enc);
00234 }
00235 }
00236
00237 return val;
00238 }
00239
00240 #ifdef NOTYET
00241
00249 static char * pgppktFormat(int_32 type, const void * data,
00250 char * formatPrefix, int padding, int element)
00251
00252 {
00253 char * val;
00254
00255 if (type != RPM_BIN_TYPE) {
00256 val = xstrdup(_("(not a blob)"));
00257 } else {
00258 }
00259
00260 return val;
00261 }
00262 #endif
00263
00272 static char * depflagsFormat(int_32 type, const void * data,
00273 char * formatPrefix, int padding, int element)
00274
00275 {
00276 char * val;
00277 char buf[10];
00278 int anint = *((int_32 *) data);
00279
00280 if (type != RPM_INT32_TYPE) {
00281 val = xstrdup(_("(not a number)"));
00282 } else {
00283 buf[0] = '\0';
00284
00285 if (anint & RPMSENSE_LESS)
00286 strcat(buf, "<");
00287 if (anint & RPMSENSE_GREATER)
00288 strcat(buf, ">");
00289 if (anint & RPMSENSE_EQUAL)
00290 strcat(buf, "=");
00291
00292 val = xmalloc(5 + padding);
00293 strcat(formatPrefix, "s");
00294
00295 sprintf(val, formatPrefix, buf);
00296
00297 }
00298
00299 return val;
00300 }
00301
00310 static int fsnamesTag( Header h, int_32 * type,
00311 void ** data, int_32 * count,
00312 int * freeData)
00313
00314
00315
00316 {
00317 const char ** list;
00318
00319 if (rpmGetFilesystemList(&list, count)) {
00320 return 1;
00321 }
00322
00323 *type = RPM_STRING_ARRAY_TYPE;
00324 *((const char ***) data) = list;
00325
00326 *freeData = 0;
00327
00328 return 0;
00329 }
00330
00339 static int instprefixTag(Header h, rpmTagType * type,
00340 const void ** data,
00341 int_32 * count,
00342 int * freeData)
00343
00344 {
00345 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00346 HFD_t hfd = headerFreeData;
00347 rpmTagType ipt;
00348 char ** array;
00349
00350 if (hge(h, RPMTAG_INSTALLPREFIX, type, (void **)data, count)) {
00351 if (freeData) *freeData = 0;
00352 return 0;
00353 } else if (hge(h, RPMTAG_INSTPREFIXES, &ipt, (void **) &array, count)) {
00354 if (data) *data = xstrdup(array[0]);
00355 if (freeData) *freeData = 1;
00356 if (type) *type = RPM_STRING_TYPE;
00357 array = hfd(array, ipt);
00358 return 0;
00359 }
00360
00361 return 1;
00362 }
00363
00372 static int fssizesTag(Header h, rpmTagType * type,
00373 const void ** data, int_32 * count,
00374 int * freeData)
00375
00376
00377
00378
00379 {
00380 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00381 const char ** filenames;
00382 int_32 * filesizes;
00383 uint_32 * usages;
00384 int numFiles;
00385
00386 if (!hge(h, RPMTAG_FILESIZES, NULL, (void **) &filesizes, &numFiles)) {
00387 filesizes = NULL;
00388 numFiles = 0;
00389 filenames = NULL;
00390 } else {
00391 rpmBuildFileList(h, &filenames, &numFiles);
00392 }
00393
00394 if (rpmGetFilesystemList(NULL, count)) {
00395 return 1;
00396 }
00397
00398 *type = RPM_INT32_TYPE;
00399 *freeData = 1;
00400
00401 if (filenames == NULL) {
00402 usages = xcalloc((*count), sizeof(usages));
00403 *data = usages;
00404
00405 return 0;
00406 }
00407
00408 if (rpmGetFilesystemUsage(filenames, filesizes, numFiles, &usages, 0))
00409 return 1;
00410
00411 *data = usages;
00412
00413 filenames = _free(filenames);
00414
00415 return 0;
00416 }
00417
00426 static int triggercondsTag(Header h, rpmTagType * type,
00427 const void ** data, int_32 * count,
00428 int * freeData)
00429
00430 {
00431 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00432 HFD_t hfd = headerFreeData;
00433 rpmTagType tnt, tvt, tst;
00434 int_32 * indices, * flags;
00435 char ** names, ** versions;
00436 int numNames, numScripts;
00437 char ** conds, ** s;
00438 char * item, * flagsStr;
00439 char * chptr;
00440 int i, j, xx;
00441 char buf[5];
00442
00443 if (!hge(h, RPMTAG_TRIGGERNAME, &tnt, (void **) &names, &numNames)) {
00444 *freeData = 0;
00445 return 0;
00446 }
00447
00448 xx = hge(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &indices, NULL);
00449 xx = hge(h, RPMTAG_TRIGGERFLAGS, NULL, (void **) &flags, NULL);
00450 xx = hge(h, RPMTAG_TRIGGERVERSION, &tvt, (void **) &versions, NULL);
00451 xx = hge(h, RPMTAG_TRIGGERSCRIPTS, &tst, (void **) &s, &numScripts);
00452 s = hfd(s, tst);
00453
00454 *freeData = 1;
00455 *data = conds = xmalloc(sizeof(*conds) * numScripts);
00456 *count = numScripts;
00457 *type = RPM_STRING_ARRAY_TYPE;
00458 for (i = 0; i < numScripts; i++) {
00459 chptr = xstrdup("");
00460
00461 for (j = 0; j < numNames; j++) {
00462 if (indices[j] != i)
00463 continue;
00464
00465 item = xmalloc(strlen(names[j]) + strlen(versions[j]) + 20);
00466 if (flags[j] & RPMSENSE_SENSEMASK) {
00467 buf[0] = '%', buf[1] = '\0';
00468 flagsStr = depflagsFormat(RPM_INT32_TYPE, flags, buf, 0, j);
00469 sprintf(item, "%s %s %s", names[j], flagsStr, versions[j]);
00470 flagsStr = _free(flagsStr);
00471 } else {
00472 strcpy(item, names[j]);
00473 }
00474
00475 chptr = xrealloc(chptr, strlen(chptr) + strlen(item) + 5);
00476 if (*chptr != '\0') strcat(chptr, ", ");
00477 strcat(chptr, item);
00478 item = _free(item);
00479 }
00480
00481 conds[i] = chptr;
00482 }
00483
00484 names = hfd(names, tnt);
00485 versions = hfd(versions, tvt);
00486
00487 return 0;
00488 }
00489
00498 static int triggertypeTag(Header h, rpmTagType * type,
00499 const void ** data, int_32 * count,
00500 int * freeData)
00501
00502 {
00503 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00504 HFD_t hfd = headerFreeData;
00505 rpmTagType tst;
00506 int_32 * indices, * flags;
00507 const char ** conds;
00508 const char ** s;
00509 int i, j, xx;
00510 int numScripts, numNames;
00511
00512 if (!hge(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &indices, &numNames)) {
00513 *freeData = 0;
00514 return 1;
00515 }
00516
00517 xx = hge(h, RPMTAG_TRIGGERFLAGS, NULL, (void **) &flags, NULL);
00518 xx = hge(h, RPMTAG_TRIGGERSCRIPTS, &tst, (void **) &s, &numScripts);
00519 s = hfd(s, tst);
00520
00521 *freeData = 1;
00522 *data = conds = xmalloc(sizeof(*conds) * numScripts);
00523 *count = numScripts;
00524 *type = RPM_STRING_ARRAY_TYPE;
00525 for (i = 0; i < numScripts; i++) {
00526 for (j = 0; j < numNames; j++) {
00527 if (indices[j] != i)
00528 continue;
00529
00530 if (flags[j] & RPMSENSE_TRIGGERIN)
00531 conds[i] = xstrdup("in");
00532 else if (flags[j] & RPMSENSE_TRIGGERUN)
00533 conds[i] = xstrdup("un");
00534 else
00535 conds[i] = xstrdup("postun");
00536 break;
00537 }
00538 }
00539
00540 return 0;
00541 }
00542
00551 static int filenamesTag(Header h, rpmTagType * type,
00552 const void ** data, int_32 * count,
00553 int * freeData)
00554
00555 {
00556 *type = RPM_STRING_ARRAY_TYPE;
00557
00558 rpmBuildFileList(h, (const char ***) data, count);
00559 *freeData = 1;
00560
00561 *freeData = 0;
00562
00563 return 0;
00564 }
00565
00566
00567
00568
00569
00570 int _nl_msg_cat_cntr;
00571
00572
00573 static const char * language = "LANGUAGE";
00574
00575
00576 static const char * _macro_i18ndomains =
00577 "%{?_i18ndomains:%{_i18ndomains}}";
00578
00588 static int i18nTag(Header h, int_32 tag, rpmTagType * type,
00589 const void ** data, int_32 * count,
00590 int * freeData)
00591
00592
00593 {
00594 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00595 char * dstring = rpmExpand(_macro_i18ndomains, NULL);
00596 int rc;
00597
00598 *type = RPM_STRING_TYPE;
00599 *data = NULL;
00600 *count = 0;
00601 *freeData = 0;
00602
00603 if (dstring && *dstring) {
00604 char *domain, *de;
00605 const char * langval;
00606 const char * msgkey;
00607 const char * msgid;
00608
00609 { const char * tn = tagName(tag);
00610 const char * n;
00611 char * mk;
00612 (void) headerNVR(h, &n, NULL, NULL);
00613 mk = alloca(strlen(n) + strlen(tn) + sizeof("()"));
00614 sprintf(mk, "%s(%s)", n, tn);
00615 msgkey = mk;
00616 }
00617
00618
00619 langval = getenv(language);
00620 (void) setenv(language, "en_US", 1);
00621 ++_nl_msg_cat_cntr;
00622
00623 msgid = NULL;
00624
00625 for (domain = dstring; domain != NULL; domain = de) {
00626 de = strchr(domain, ':');
00627 if (de) *de++ = '\0';
00628 msgid = dgettext(domain, msgkey) ;
00629 if (msgid != msgkey) break;
00630 }
00631
00632
00633
00634 if (langval)
00635 (void) setenv(language, langval, 1);
00636 else
00637 unsetenv(language);
00638 ++_nl_msg_cat_cntr;
00639
00640 if (domain && msgid) {
00641 *data = dgettext(domain, msgid) ;
00642 *data = xstrdup(*data);
00643 *count = 1;
00644 *freeData = 1;
00645 }
00646 dstring = _free(dstring);
00647 if (*data)
00648 return 0;
00649 }
00650
00651 dstring = _free(dstring);
00652
00653 rc = hge(h, tag, type, (void **)data, count);
00654
00655 if (rc && (*data) != NULL) {
00656 *data = xstrdup(*data);
00657 *freeData = 1;
00658 return 0;
00659 }
00660
00661 *freeData = 0;
00662 *data = NULL;
00663 *count = 0;
00664 return 1;
00665 }
00666
00675 static int summaryTag(Header h, rpmTagType * type,
00676 const void ** data, int_32 * count,
00677 int * freeData)
00678
00679
00680 {
00681 return i18nTag(h, RPMTAG_SUMMARY, type, data, count, freeData);
00682 }
00683
00692 static int descriptionTag(Header h, rpmTagType * type,
00693 const void ** data, int_32 * count,
00694 int * freeData)
00695
00696
00697 {
00698 return i18nTag(h, RPMTAG_DESCRIPTION, type, data, count, freeData);
00699 }
00700
00709 static int groupTag(Header h, rpmTagType * type,
00710 const void ** data, int_32 * count,
00711 int * freeData)
00712
00713
00714 {
00715 return i18nTag(h, RPMTAG_GROUP, type, data, count, freeData);
00716 }
00717
00718
00719 const struct headerSprintfExtension_s rpmHeaderFormats[] = {
00720 { HEADER_EXT_TAG, "RPMTAG_GROUP", { groupTag } },
00721 { HEADER_EXT_TAG, "RPMTAG_DESCRIPTION", { descriptionTag } },
00722 { HEADER_EXT_TAG, "RPMTAG_SUMMARY", { summaryTag } },
00723 { HEADER_EXT_TAG, "RPMTAG_FILENAMES", { filenamesTag } },
00724 { HEADER_EXT_TAG, "RPMTAG_FSSIZES", { fssizesTag } },
00725 { HEADER_EXT_TAG, "RPMTAG_FSNAMES", { fsnamesTag } },
00726 { HEADER_EXT_TAG, "RPMTAG_INSTALLPREFIX", { instprefixTag } },
00727 { HEADER_EXT_TAG, "RPMTAG_TRIGGERCONDS", { triggercondsTag } },
00728 { HEADER_EXT_TAG, "RPMTAG_TRIGGERTYPE", { triggertypeTag } },
00729 { HEADER_EXT_FORMAT, "armor", { armorFormat } },
00730 { HEADER_EXT_FORMAT, "base64", { base64Format } },
00731 #ifdef NOTYET
00732 { HEADER_EXT_FORMAT, "pgppkt", { pgppktFormat } },
00733 #endif
00734 { HEADER_EXT_FORMAT, "depflags", { depflagsFormat } },
00735 { HEADER_EXT_FORMAT, "fflags", { fflagsFormat } },
00736 { HEADER_EXT_FORMAT, "perms", { permsFormat } },
00737 { HEADER_EXT_FORMAT, "permissions", { permsFormat } },
00738 { HEADER_EXT_FORMAT, "triggertype", { triggertypeFormat } },
00739 { HEADER_EXT_MORE, NULL, { (void *) headerDefaultFormats } }
00740 } ;
00741