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 char * nothingFormat(int_32 type, const void * data,
00311 char * formatPrefix, int padding, int element)
00312
00313 {
00314 char * val;
00315 val = xmalloc(2 + padding);
00316 strcat(formatPrefix, "s");
00317
00318 sprintf(val, formatPrefix, "");
00319
00320
00321 return val;
00322 }
00323
00332 static int fsnamesTag( Header h, int_32 * type,
00333 void ** data, int_32 * count,
00334 int * freeData)
00335
00336
00337
00338 {
00339 const char ** list;
00340
00341 if (rpmGetFilesystemList(&list, count)) {
00342 return 1;
00343 }
00344
00345 *type = RPM_STRING_ARRAY_TYPE;
00346 *((const char ***) data) = list;
00347
00348 *freeData = 0;
00349
00350 return 0;
00351 }
00352
00361 static int instprefixTag(Header h, rpmTagType * type,
00362 const void ** data,
00363 int_32 * count,
00364 int * freeData)
00365
00366 {
00367 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00368 HFD_t hfd = headerFreeData;
00369 rpmTagType ipt;
00370 char ** array;
00371
00372 if (hge(h, RPMTAG_INSTALLPREFIX, type, (void **)data, count)) {
00373 if (freeData) *freeData = 0;
00374 return 0;
00375 } else if (hge(h, RPMTAG_INSTPREFIXES, &ipt, (void **) &array, count)) {
00376 if (data) *data = xstrdup(array[0]);
00377 if (freeData) *freeData = 1;
00378 if (type) *type = RPM_STRING_TYPE;
00379 array = hfd(array, ipt);
00380 return 0;
00381 }
00382
00383 return 1;
00384 }
00385
00394 static int fssizesTag(Header h, rpmTagType * type,
00395 const void ** data, int_32 * count,
00396 int * freeData)
00397
00398
00399
00400
00401 {
00402 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00403 const char ** filenames;
00404 int_32 * filesizes;
00405 uint_32 * usages;
00406 int numFiles;
00407
00408 if (!hge(h, RPMTAG_FILESIZES, NULL, (void **) &filesizes, &numFiles)) {
00409 filesizes = NULL;
00410 numFiles = 0;
00411 filenames = NULL;
00412 } else {
00413 rpmBuildFileList(h, &filenames, &numFiles);
00414 }
00415
00416 if (rpmGetFilesystemList(NULL, count)) {
00417 return 1;
00418 }
00419
00420 *type = RPM_INT32_TYPE;
00421 *freeData = 1;
00422
00423 if (filenames == NULL) {
00424 usages = xcalloc((*count), sizeof(usages));
00425 *data = usages;
00426
00427 return 0;
00428 }
00429
00430 if (rpmGetFilesystemUsage(filenames, filesizes, numFiles, &usages, 0))
00431 return 1;
00432
00433 *data = usages;
00434
00435 filenames = _free(filenames);
00436
00437 return 0;
00438 }
00439
00448 static int triggercondsTag(Header h, rpmTagType * type,
00449 const void ** data, int_32 * count,
00450 int * freeData)
00451
00452 {
00453 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00454 HFD_t hfd = headerFreeData;
00455 rpmTagType tnt, tvt, tst;
00456 int_32 * indices, * flags;
00457 char ** names, ** versions;
00458 int numNames, numScripts;
00459 char ** conds, ** s;
00460 char * item, * flagsStr;
00461 char * chptr;
00462 int i, j, xx;
00463 char buf[5];
00464
00465 if (!hge(h, RPMTAG_TRIGGERNAME, &tnt, (void **) &names, &numNames)) {
00466 *freeData = 0;
00467 return 0;
00468 }
00469
00470 xx = hge(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &indices, NULL);
00471 xx = hge(h, RPMTAG_TRIGGERFLAGS, NULL, (void **) &flags, NULL);
00472 xx = hge(h, RPMTAG_TRIGGERVERSION, &tvt, (void **) &versions, NULL);
00473 xx = hge(h, RPMTAG_TRIGGERSCRIPTS, &tst, (void **) &s, &numScripts);
00474 s = hfd(s, tst);
00475
00476 *freeData = 1;
00477 *data = conds = xmalloc(sizeof(*conds) * numScripts);
00478 *count = numScripts;
00479 *type = RPM_STRING_ARRAY_TYPE;
00480 for (i = 0; i < numScripts; i++) {
00481 chptr = xstrdup("");
00482
00483 for (j = 0; j < numNames; j++) {
00484 if (indices[j] != i)
00485 continue;
00486
00487 item = xmalloc(strlen(names[j]) + strlen(versions[j]) + 20);
00488 if (flags[j] & RPMSENSE_SENSEMASK) {
00489 buf[0] = '%', buf[1] = '\0';
00490 flagsStr = depflagsFormat(RPM_INT32_TYPE, flags, buf, 0, j);
00491 sprintf(item, "%s %s %s", names[j], flagsStr, versions[j]);
00492 flagsStr = _free(flagsStr);
00493 } else {
00494 strcpy(item, names[j]);
00495 }
00496
00497 chptr = xrealloc(chptr, strlen(chptr) + strlen(item) + 5);
00498 if (*chptr != '\0') strcat(chptr, ", ");
00499 strcat(chptr, item);
00500 item = _free(item);
00501 }
00502
00503 conds[i] = chptr;
00504 }
00505
00506 names = hfd(names, tnt);
00507 versions = hfd(versions, tvt);
00508
00509 return 0;
00510 }
00511
00520 static int triggertypeTag(Header h, rpmTagType * type,
00521 const void ** data, int_32 * count,
00522 int * freeData)
00523
00524 {
00525 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00526 HFD_t hfd = headerFreeData;
00527 rpmTagType tst;
00528 int_32 * indices, * flags;
00529 const char ** conds;
00530 const char ** s;
00531 int i, j, xx;
00532 int numScripts, numNames;
00533
00534 if (!hge(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &indices, &numNames)) {
00535 *freeData = 0;
00536 return 1;
00537 }
00538
00539 xx = hge(h, RPMTAG_TRIGGERFLAGS, NULL, (void **) &flags, NULL);
00540 xx = hge(h, RPMTAG_TRIGGERSCRIPTS, &tst, (void **) &s, &numScripts);
00541 s = hfd(s, tst);
00542
00543 *freeData = 1;
00544 *data = conds = xmalloc(sizeof(*conds) * numScripts);
00545 *count = numScripts;
00546 *type = RPM_STRING_ARRAY_TYPE;
00547 for (i = 0; i < numScripts; i++) {
00548 for (j = 0; j < numNames; j++) {
00549 if (indices[j] != i)
00550 continue;
00551
00552 if (flags[j] & RPMSENSE_TRIGGERIN)
00553 conds[i] = xstrdup("in");
00554 else if (flags[j] & RPMSENSE_TRIGGERUN)
00555 conds[i] = xstrdup("un");
00556 else
00557 conds[i] = xstrdup("postun");
00558 break;
00559 }
00560 }
00561
00562 return 0;
00563 }
00564
00573 static int filenamesTag(Header h, rpmTagType * type,
00574 const void ** data, int_32 * count,
00575 int * freeData)
00576
00577 {
00578 *type = RPM_STRING_ARRAY_TYPE;
00579
00580 rpmBuildFileList(h, (const char ***) data, count);
00581 *freeData = 1;
00582
00583 *freeData = 0;
00584
00585 return 0;
00586 }
00587
00588
00589
00590
00591
00592 int _nl_msg_cat_cntr;
00593
00594
00595 static const char * language = "LANGUAGE";
00596
00597
00598 static const char * _macro_i18ndomains =
00599 "%{?_i18ndomains:%{_i18ndomains}}";
00600
00610 static int i18nTag(Header h, int_32 tag, rpmTagType * type,
00611 const void ** data, int_32 * count,
00612 int * freeData)
00613
00614
00615 {
00616 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00617 char * dstring = rpmExpand(_macro_i18ndomains, NULL);
00618 int rc;
00619
00620 *type = RPM_STRING_TYPE;
00621 *data = NULL;
00622 *count = 0;
00623 *freeData = 0;
00624
00625 if (dstring && *dstring) {
00626 char *domain, *de;
00627 const char * langval;
00628 const char * msgkey;
00629 const char * msgid;
00630
00631 { const char * tn = tagName(tag);
00632 const char * n;
00633 char * mk;
00634 (void) headerNVR(h, &n, NULL, NULL);
00635 mk = alloca(strlen(n) + strlen(tn) + sizeof("()"));
00636 sprintf(mk, "%s(%s)", n, tn);
00637 msgkey = mk;
00638 }
00639
00640
00641 langval = getenv(language);
00642 (void) setenv(language, "en_US", 1);
00643 ++_nl_msg_cat_cntr;
00644
00645 msgid = NULL;
00646
00647 for (domain = dstring; domain != NULL; domain = de) {
00648 de = strchr(domain, ':');
00649 if (de) *de++ = '\0';
00650 msgid = dgettext(domain, msgkey) ;
00651 if (msgid != msgkey) break;
00652 }
00653
00654
00655
00656 if (langval)
00657 (void) setenv(language, langval, 1);
00658 else
00659 unsetenv(language);
00660 ++_nl_msg_cat_cntr;
00661
00662 if (domain && msgid) {
00663 *data = dgettext(domain, msgid) ;
00664 *data = xstrdup(*data);
00665 *count = 1;
00666 *freeData = 1;
00667 }
00668 dstring = _free(dstring);
00669 if (*data)
00670 return 0;
00671 }
00672
00673 dstring = _free(dstring);
00674
00675 rc = hge(h, tag, type, (void **)data, count);
00676
00677 if (rc && (*data) != NULL) {
00678 *data = xstrdup(*data);
00679 *freeData = 1;
00680 return 0;
00681 }
00682
00683 *freeData = 0;
00684 *data = NULL;
00685 *count = 0;
00686 return 1;
00687 }
00688
00697 static int summaryTag(Header h, rpmTagType * type,
00698 const void ** data, int_32 * count,
00699 int * freeData)
00700
00701
00702 {
00703 return i18nTag(h, RPMTAG_SUMMARY, type, data, count, freeData);
00704 }
00705
00714 static int descriptionTag(Header h, rpmTagType * type,
00715 const void ** data, int_32 * count,
00716 int * freeData)
00717
00718
00719 {
00720 return i18nTag(h, RPMTAG_DESCRIPTION, type, data, count, freeData);
00721 }
00722
00731 static int groupTag(Header h, rpmTagType * type,
00732 const void ** data, int_32 * count,
00733 int * freeData)
00734
00735
00736 {
00737 return i18nTag(h, RPMTAG_GROUP, type, data, count, freeData);
00738 }
00739
00740
00741 const struct headerSprintfExtension_s rpmHeaderFormats[] = {
00742 { HEADER_EXT_TAG, "RPMTAG_GROUP", { groupTag } },
00743 { HEADER_EXT_TAG, "RPMTAG_DESCRIPTION", { descriptionTag } },
00744 { HEADER_EXT_TAG, "RPMTAG_SUMMARY", { summaryTag } },
00745 { HEADER_EXT_TAG, "RPMTAG_FILENAMES", { filenamesTag } },
00746 { HEADER_EXT_TAG, "RPMTAG_FSSIZES", { fssizesTag } },
00747 { HEADER_EXT_TAG, "RPMTAG_FSNAMES", { fsnamesTag } },
00748 { HEADER_EXT_TAG, "RPMTAG_INSTALLPREFIX", { instprefixTag } },
00749 { HEADER_EXT_TAG, "RPMTAG_TRIGGERCONDS", { triggercondsTag } },
00750 { HEADER_EXT_TAG, "RPMTAG_TRIGGERTYPE", { triggertypeTag } },
00751 { HEADER_EXT_FORMAT, "armor", { armorFormat } },
00752 { HEADER_EXT_FORMAT, "base64", { base64Format } },
00753 #ifdef NOTYET
00754 { HEADER_EXT_FORMAT, "pgppkt", { pgppktFormat } },
00755 #endif
00756 { HEADER_EXT_FORMAT, "depflags", { depflagsFormat } },
00757 { HEADER_EXT_FORMAT, "fflags", { fflagsFormat } },
00758 { HEADER_EXT_FORMAT, "perms", { permsFormat } },
00759 { HEADER_EXT_FORMAT, "permissions", { permsFormat } },
00760 { HEADER_EXT_FORMAT, "triggertype", { triggertypeFormat } },
00761 { HEADER_EXT_FORMAT, "nothing", { nothingFormat } },
00762 { HEADER_EXT_MORE, NULL, { (void *) headerDefaultFormats } }
00763 } ;
00764