00001
00005 #include "system.h"
00006 #include "rpmio_internal.h"
00007 #include <rpmlib.h>
00008 #include <rpmmacro.h>
00009 #include "manifest.h"
00010 #include "misc.h"
00011 #include "debug.h"
00012
00013
00014
00015
00025 static char * triggertypeFormat(int_32 type, const void * data,
00026 char * formatPrefix, int padding,
00027 int element)
00028
00029 {
00030 const int_32 * item = data;
00031 char * val;
00032
00033 if (type != RPM_INT32_TYPE)
00034 val = xstrdup(_("(not a number)"));
00035 else if (*item & RPMSENSE_TRIGGERIN)
00036 val = xstrdup("in");
00037 else
00038 val = xstrdup("un");
00039 return val;
00040 }
00041
00051 static char * permsFormat(int_32 type, const void * data,
00052 char * formatPrefix, int padding, int element)
00053
00054
00055 {
00056 char * val;
00057 char * buf;
00058
00059 if (type != RPM_INT32_TYPE) {
00060 val = xstrdup(_("(not a number)"));
00061 } else {
00062 val = xmalloc(15 + padding);
00063
00064 strcat(formatPrefix, "s");
00065
00066 buf = rpmPermsString(*((int_32 *) data));
00067
00068 sprintf(val, formatPrefix, buf);
00069
00070 buf = _free(buf);
00071 }
00072
00073 return val;
00074 }
00075
00085 static char * fflagsFormat(int_32 type, const void * data,
00086 char * formatPrefix, int padding, int element)
00087
00088
00089 {
00090 char * val;
00091 char buf[15];
00092 int anint = *((int_32 *) data);
00093
00094 if (type != RPM_INT32_TYPE) {
00095 val = xstrdup(_("(not a number)"));
00096 } else {
00097 buf[0] = '\0';
00098
00099 if (anint & RPMFILE_DOC)
00100 strcat(buf, "d");
00101 if (anint & RPMFILE_CONFIG)
00102 strcat(buf, "c");
00103 if (anint & RPMFILE_SPECFILE)
00104 strcat(buf, "s");
00105 if (anint & RPMFILE_MISSINGOK)
00106 strcat(buf, "m");
00107 if (anint & RPMFILE_NOREPLACE)
00108 strcat(buf, "n");
00109 if (anint & RPMFILE_GHOST)
00110 strcat(buf, "g");
00111 if (anint & RPMFILE_LICENSE)
00112 strcat(buf, "l");
00113 if (anint & RPMFILE_README)
00114 strcat(buf, "r");
00115
00116
00117 val = xmalloc(5 + padding);
00118
00119 strcat(formatPrefix, "s");
00120
00121
00122 sprintf(val, formatPrefix, buf);
00123
00124 }
00125
00126 return val;
00127 }
00128
00139 static char * armorFormat(int_32 type, const void * data,
00140 char * formatPrefix, int padding, int element)
00141
00142 {
00143 const char * enc;
00144 const char * s;
00145 char * t;
00146 char * val;
00147 int atype;
00148 int lc, ns, nt;
00149
00150 switch (type) {
00151 case RPM_BIN_TYPE:
00152 s = data;
00153 ns = element;
00154 atype = PGPARMOR_SIGNATURE;
00155 break;
00156 case RPM_STRING_TYPE:
00157 case RPM_STRING_ARRAY_TYPE:
00158 enc = data;
00159 if (b64decode(enc, (void **)&s, &ns))
00160 return xstrdup(_("(not base64)"));
00161 atype = PGPARMOR_PUBKEY;
00162 break;
00163 case RPM_NULL_TYPE:
00164 case RPM_CHAR_TYPE:
00165 case RPM_INT8_TYPE:
00166 case RPM_INT16_TYPE:
00167 case RPM_INT32_TYPE:
00168 case RPM_I18NSTRING_TYPE:
00169 default:
00170 return xstrdup(_("(invalid type)"));
00171 break;
00172 }
00173
00174 nt = ((ns + 2) / 3) * 4;
00175
00176
00177 if (b64encode_chars_per_line > 0 && b64encode_eolstr != NULL) {
00178 lc = (nt + b64encode_chars_per_line - 1) / b64encode_chars_per_line;
00179 if (((nt + b64encode_chars_per_line - 1) % b64encode_chars_per_line) != 0)
00180 ++lc;
00181 nt += lc * strlen(b64encode_eolstr);
00182 }
00183
00184
00185 nt += 512;
00186
00187
00188 val = t = xmalloc(nt + padding + 1);
00189 *t = '\0';
00190 t = stpcpy(t, "-----BEGIN PGP ");
00191 t = stpcpy(t, pgpValStr(pgpArmorTbl, atype));
00192
00193 t = stpcpy( stpcpy(t, "-----\nVersion: rpm-"), RPMVERSION);
00194
00195 t = stpcpy(t, " (beecrypt-2.2.0)\n\n");
00196
00197 if ((enc = b64encode(s, ns)) != NULL) {
00198 t = stpcpy(t, enc);
00199 enc = _free(enc);
00200 if ((enc = b64crc(s, ns)) != NULL) {
00201 *t++ = '=';
00202 t = stpcpy(t, enc);
00203 enc = _free(enc);
00204 }
00205 }
00206
00207 t = stpcpy(t, "-----END PGP ");
00208 t = stpcpy(t, pgpValStr(pgpArmorTbl, atype));
00209 t = stpcpy(t, "-----\n");
00210
00211
00212
00213 if (s != data) s = _free(s);
00214
00215
00216 return val;
00217 }
00218
00229 static char * base64Format(int_32 type, const void * data,
00230 char * formatPrefix, int padding, int element)
00231
00232 {
00233 char * val;
00234
00235 if (type != RPM_BIN_TYPE) {
00236 val = xstrdup(_("(not a blob)"));
00237 } else {
00238 const char * enc;
00239 char * t;
00240 int lc;
00241 int nt = ((element + 2) / 3) * 4;
00242
00243
00244
00245
00246 if (b64encode_chars_per_line > 0 && b64encode_eolstr != NULL) {
00247 lc = (nt + b64encode_chars_per_line - 1) / b64encode_chars_per_line;
00248 if (((nt + b64encode_chars_per_line - 1) % b64encode_chars_per_line) != 0)
00249 ++lc;
00250 nt += lc * strlen(b64encode_eolstr);
00251 }
00252
00253
00254 val = t = xmalloc(nt + padding + 1);
00255
00256 *t = '\0';
00257 if ((enc = b64encode(data, element)) != NULL) {
00258 t = stpcpy(t, enc);
00259 enc = _free(enc);
00260 }
00261
00262 }
00263
00264 return val;
00265 }
00266
00276 static char * pgpsigFormat(int_32 type, const void * data,
00277 char * formatPrefix, int padding,
00278 int element)
00279
00280
00281 {
00282 char * val, * t;
00283
00284 if (type != RPM_BIN_TYPE) {
00285 val = xstrdup(_("(not a blob)"));
00286 } else {
00287 unsigned char * pkt = (byte *) data;
00288 unsigned int pktlen = 0;
00289
00290 unsigned int v = *pkt;
00291
00292 pgpTag tag = 0;
00293 unsigned int plen;
00294 unsigned int hlen = 0;
00295
00296 if (v & 0x80) {
00297 if (v & 0x40) {
00298 tag = (v & 0x3f);
00299 plen = pgpLen(pkt+1, &hlen);
00300 } else {
00301 tag = (v >> 2) & 0xf;
00302 plen = (1 << (v & 0x3));
00303 hlen = pgpGrab(pkt+1, plen);
00304 }
00305
00306 pktlen = 1 + plen + hlen;
00307 }
00308
00309 if (pktlen == 0 || tag != PGPTAG_SIGNATURE) {
00310 val = xstrdup(_("(not an OpenPGP signature)"));
00311 } else {
00312 pgpDig dig = pgpNewDig();
00313 pgpDigParams sigp = &dig->signature;
00314 size_t nb = 80;
00315
00316 (void) pgpPrtPkts(pkt, pktlen, dig, 0);
00317
00318 val = t = xmalloc(nb + 1);
00319
00320
00321 switch (sigp->pubkey_algo) {
00322 case PGPPUBKEYALGO_DSA:
00323 t = stpcpy(t, "DSA");
00324 break;
00325 case PGPPUBKEYALGO_RSA:
00326 t = stpcpy(t, "RSA");
00327 break;
00328 default:
00329 sprintf(t, "%d", sigp->pubkey_algo);
00330 t += strlen(t);
00331 break;
00332 }
00333 *t++ = '/';
00334 switch (sigp->hash_algo) {
00335 case PGPHASHALGO_MD5:
00336 t = stpcpy(t, "MD5");
00337 break;
00338 case PGPHASHALGO_SHA1:
00339 t = stpcpy(t, "SHA1");
00340 break;
00341 default:
00342 sprintf(t, "%d", sigp->hash_algo);
00343 t += strlen(t);
00344 break;
00345 }
00346
00347 t = stpcpy(t, ", ");
00348
00349
00350 { time_t dateint = pgpGrab(sigp->time, sizeof(sigp->time));
00351 struct tm * tstruct = localtime(&dateint);
00352 if (tstruct)
00353 (void) strftime(t, (nb - (t - val)), "%c", tstruct);
00354 }
00355 t += strlen(t);
00356 t = stpcpy(t, ", Key ID ");
00357 t = stpcpy(t, pgpHexStr(sigp->signid, sizeof(sigp->signid)));
00358
00359
00360 dig = pgpFreeDig(dig);
00361 }
00362 }
00363
00364 return val;
00365 }
00366
00376 static char * depflagsFormat(int_32 type, const void * data,
00377 char * formatPrefix, int padding, int element)
00378
00379
00380 {
00381 char * val;
00382 char buf[10];
00383 int anint = *((int_32 *) data);
00384
00385 if (type != RPM_INT32_TYPE) {
00386 val = xstrdup(_("(not a number)"));
00387 } else {
00388 buf[0] = '\0';
00389
00390
00391 if (anint & RPMSENSE_LESS)
00392 strcat(buf, "<");
00393 if (anint & RPMSENSE_GREATER)
00394 strcat(buf, ">");
00395 if (anint & RPMSENSE_EQUAL)
00396 strcat(buf, "=");
00397
00398
00399 val = xmalloc(5 + padding);
00400
00401 strcat(formatPrefix, "s");
00402
00403
00404 sprintf(val, formatPrefix, buf);
00405
00406 }
00407
00408 return val;
00409 }
00410
00420 static int fsnamesTag( Header h, int_32 * type,
00421 void ** data, int_32 * count,
00422 int * freeData)
00423
00424
00425
00426
00427
00428 {
00429 const char ** list;
00430
00431
00432 if (rpmGetFilesystemList(&list, count))
00433 return 1;
00434
00435
00436 if (type) *type = RPM_STRING_ARRAY_TYPE;
00437 if (data) *((const char ***) data) = list;
00438 if (freeData) *freeData = 0;
00439
00440 return 0;
00441 }
00442
00452 static int instprefixTag(Header h, rpmTagType * type,
00453 const void ** data,
00454 int_32 * count,
00455 int * freeData)
00456
00457
00458
00459 {
00460 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00461 HFD_t hfd = headerFreeData;
00462 rpmTagType ipt;
00463 char ** array;
00464
00465 if (hge(h, RPMTAG_INSTALLPREFIX, type, (void **)data, count)) {
00466 if (freeData) *freeData = 0;
00467 return 0;
00468 } else if (hge(h, RPMTAG_INSTPREFIXES, &ipt, (void **) &array, count)) {
00469 if (type) *type = RPM_STRING_TYPE;
00470
00471 if (data) *data = xstrdup(array[0]);
00472
00473 if (freeData) *freeData = 1;
00474 array = hfd(array, ipt);
00475 return 0;
00476 }
00477
00478 return 1;
00479 }
00480
00490 static int fssizesTag(Header h, rpmTagType * type,
00491 const void ** data, int_32 * count,
00492 int * freeData)
00493
00494
00495
00496
00497
00498
00499 {
00500 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00501 const char ** filenames;
00502 int_32 * filesizes;
00503 uint_32 * usages;
00504 int numFiles;
00505
00506 if (!hge(h, RPMTAG_FILESIZES, NULL, (void **) &filesizes, &numFiles)) {
00507 filesizes = NULL;
00508 numFiles = 0;
00509 filenames = NULL;
00510 } else {
00511 rpmBuildFileList(h, &filenames, &numFiles);
00512 }
00513
00514
00515 if (rpmGetFilesystemList(NULL, count))
00516 return 1;
00517
00518
00519 *type = RPM_INT32_TYPE;
00520 *freeData = 1;
00521
00522 if (filenames == NULL) {
00523 usages = xcalloc((*count), sizeof(usages));
00524 *data = usages;
00525
00526 return 0;
00527 }
00528
00529
00530 if (rpmGetFilesystemUsage(filenames, filesizes, numFiles, &usages, 0))
00531 return 1;
00532
00533
00534 *data = usages;
00535
00536 filenames = _free(filenames);
00537
00538 return 0;
00539 }
00540
00550
00551 static int triggercondsTag(Header h, rpmTagType * type,
00552 const void ** data, int_32 * count,
00553 int * freeData)
00554
00555
00556
00557 {
00558 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00559 HFD_t hfd = headerFreeData;
00560 rpmTagType tnt, tvt, tst;
00561 int_32 * indices, * flags;
00562 char ** names, ** versions;
00563 int numNames, numScripts;
00564 char ** conds, ** s;
00565 char * item, * flagsStr;
00566 char * chptr;
00567 int i, j, xx;
00568 char buf[5];
00569
00570 if (!hge(h, RPMTAG_TRIGGERNAME, &tnt, (void **) &names, &numNames)) {
00571 *freeData = 0;
00572 return 0;
00573 }
00574
00575 xx = hge(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &indices, NULL);
00576 xx = hge(h, RPMTAG_TRIGGERFLAGS, NULL, (void **) &flags, NULL);
00577 xx = hge(h, RPMTAG_TRIGGERVERSION, &tvt, (void **) &versions, NULL);
00578 xx = hge(h, RPMTAG_TRIGGERSCRIPTS, &tst, (void **) &s, &numScripts);
00579 s = hfd(s, tst);
00580
00581 *freeData = 1;
00582 *data = conds = xmalloc(sizeof(*conds) * numScripts);
00583 *count = numScripts;
00584 *type = RPM_STRING_ARRAY_TYPE;
00585 for (i = 0; i < numScripts; i++) {
00586 chptr = xstrdup("");
00587
00588 for (j = 0; j < numNames; j++) {
00589 if (indices[j] != i)
00590 continue;
00591
00592 item = xmalloc(strlen(names[j]) + strlen(versions[j]) + 20);
00593 if (flags[j] & RPMSENSE_SENSEMASK) {
00594 buf[0] = '%', buf[1] = '\0';
00595 flagsStr = depflagsFormat(RPM_INT32_TYPE, flags, buf, 0, j);
00596 sprintf(item, "%s %s %s", names[j], flagsStr, versions[j]);
00597 flagsStr = _free(flagsStr);
00598 } else {
00599 strcpy(item, names[j]);
00600 }
00601
00602 chptr = xrealloc(chptr, strlen(chptr) + strlen(item) + 5);
00603 if (*chptr != '\0') strcat(chptr, ", ");
00604 strcat(chptr, item);
00605 item = _free(item);
00606 }
00607
00608 conds[i] = chptr;
00609 }
00610
00611 names = hfd(names, tnt);
00612 versions = hfd(versions, tvt);
00613
00614 return 0;
00615 }
00616
00617
00627 static int triggertypeTag(Header h, rpmTagType * type,
00628 const void ** data, int_32 * count,
00629 int * freeData)
00630
00631
00632
00633 {
00634 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00635 HFD_t hfd = headerFreeData;
00636 rpmTagType tst;
00637 int_32 * indices, * flags;
00638 const char ** conds;
00639 const char ** s;
00640 int i, j, xx;
00641 int numScripts, numNames;
00642
00643 if (!hge(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &indices, &numNames)) {
00644 *freeData = 0;
00645 return 1;
00646 }
00647
00648 xx = hge(h, RPMTAG_TRIGGERFLAGS, NULL, (void **) &flags, NULL);
00649 xx = hge(h, RPMTAG_TRIGGERSCRIPTS, &tst, (void **) &s, &numScripts);
00650 s = hfd(s, tst);
00651
00652 *freeData = 1;
00653 *data = conds = xmalloc(sizeof(*conds) * numScripts);
00654 *count = numScripts;
00655 *type = RPM_STRING_ARRAY_TYPE;
00656 for (i = 0; i < numScripts; i++) {
00657 for (j = 0; j < numNames; j++) {
00658 if (indices[j] != i)
00659 continue;
00660
00661 if (flags[j] & RPMSENSE_TRIGGERIN)
00662 conds[i] = xstrdup("in");
00663 else if (flags[j] & RPMSENSE_TRIGGERUN)
00664 conds[i] = xstrdup("un");
00665 else
00666 conds[i] = xstrdup("postun");
00667 break;
00668 }
00669 }
00670
00671 return 0;
00672 }
00673
00683 static int filenamesTag(Header h, rpmTagType * type,
00684 const void ** data, int_32 * count,
00685 int * freeData)
00686
00687
00688
00689 {
00690 *type = RPM_STRING_ARRAY_TYPE;
00691
00692 rpmBuildFileList(h, (const char ***) data, count);
00693 *freeData = 1;
00694
00695 *freeData = 0;
00696
00697 return 0;
00698 }
00699
00700
00701
00702
00703
00704 int _nl_msg_cat_cntr;
00705
00706
00707 static const char * language = "LANGUAGE";
00708
00709
00710 static const char * _macro_i18ndomains =
00711 "%{?_i18ndomains:%{_i18ndomains}}";
00712
00723 static int i18nTag(Header h, int_32 tag, rpmTagType * type,
00724 const void ** data, int_32 * count,
00725 int * freeData)
00726
00727
00728
00729
00730 {
00731 HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00732 char * dstring = rpmExpand(_macro_i18ndomains, NULL);
00733 int rc;
00734
00735 *type = RPM_STRING_TYPE;
00736 *data = NULL;
00737 *count = 0;
00738 *freeData = 0;
00739
00740 if (dstring && *dstring) {
00741 char *domain, *de;
00742 const char * langval;
00743 const char * msgkey;
00744 const char * msgid;
00745
00746 { const char * tn = tagName(tag);
00747 const char * n;
00748 char * mk;
00749 (void) headerNVR(h, &n, NULL, NULL);
00750 mk = alloca(strlen(n) + strlen(tn) + sizeof("()"));
00751 sprintf(mk, "%s(%s)", n, tn);
00752 msgkey = mk;
00753 }
00754
00755
00756 langval = getenv(language);
00757 (void) setenv(language, "en_US", 1);
00758 ++_nl_msg_cat_cntr;
00759
00760 msgid = NULL;
00761
00762 for (domain = dstring; domain != NULL; domain = de) {
00763 de = strchr(domain, ':');
00764 if (de) *de++ = '\0';
00765 msgid = dgettext(domain, msgkey) ;
00766 if (msgid != msgkey) break;
00767 }
00768
00769
00770
00771 if (langval)
00772 (void) setenv(language, langval, 1);
00773 else
00774 unsetenv(language);
00775 ++_nl_msg_cat_cntr;
00776
00777 if (domain && msgid) {
00778 *data = dgettext(domain, msgid) ;
00779 *data = xstrdup(*data);
00780 *count = 1;
00781 *freeData = 1;
00782 }
00783 dstring = _free(dstring);
00784 if (*data)
00785 return 0;
00786 }
00787
00788 dstring = _free(dstring);
00789
00790 rc = hge(h, tag, type, (void **)data, count);
00791
00792 if (rc && (*data) != NULL) {
00793 *data = xstrdup(*data);
00794 *freeData = 1;
00795 return 0;
00796 }
00797
00798 *freeData = 0;
00799 *data = NULL;
00800 *count = 0;
00801 return 1;
00802 }
00803
00813 static int summaryTag(Header h, rpmTagType * type,
00814 const void ** data, int_32 * count,
00815 int * freeData)
00816
00817
00818
00819
00820 {
00821 return i18nTag(h, RPMTAG_SUMMARY, type, data, count, freeData);
00822 }
00823
00833 static int descriptionTag(Header h, rpmTagType * type,
00834 const void ** data, int_32 * count,
00835 int * freeData)
00836
00837
00838
00839
00840 {
00841 return i18nTag(h, RPMTAG_DESCRIPTION, type, data, count, freeData);
00842 }
00843
00853 static int groupTag(Header h, rpmTagType * type,
00854 const void ** data, int_32 * count,
00855 int * freeData)
00856
00857
00858
00859
00860 {
00861 return i18nTag(h, RPMTAG_GROUP, type, data, count, freeData);
00862 }
00863
00864
00865 const struct headerSprintfExtension_s rpmHeaderFormats[] = {
00866 { HEADER_EXT_TAG, "RPMTAG_GROUP", { groupTag } },
00867 { HEADER_EXT_TAG, "RPMTAG_DESCRIPTION", { descriptionTag } },
00868 { HEADER_EXT_TAG, "RPMTAG_SUMMARY", { summaryTag } },
00869 { HEADER_EXT_TAG, "RPMTAG_FILENAMES", { filenamesTag } },
00870 { HEADER_EXT_TAG, "RPMTAG_FSSIZES", { fssizesTag } },
00871 { HEADER_EXT_TAG, "RPMTAG_FSNAMES", { fsnamesTag } },
00872 { HEADER_EXT_TAG, "RPMTAG_INSTALLPREFIX", { instprefixTag } },
00873 { HEADER_EXT_TAG, "RPMTAG_TRIGGERCONDS", { triggercondsTag } },
00874 { HEADER_EXT_TAG, "RPMTAG_TRIGGERTYPE", { triggertypeTag } },
00875 { HEADER_EXT_FORMAT, "armor", { armorFormat } },
00876 { HEADER_EXT_FORMAT, "base64", { base64Format } },
00877 { HEADER_EXT_FORMAT, "pgpsig", { pgpsigFormat } },
00878 { HEADER_EXT_FORMAT, "depflags", { depflagsFormat } },
00879 { HEADER_EXT_FORMAT, "fflags", { fflagsFormat } },
00880 { HEADER_EXT_FORMAT, "perms", { permsFormat } },
00881 { HEADER_EXT_FORMAT, "permissions", { permsFormat } },
00882 { HEADER_EXT_FORMAT, "triggertype", { triggertypeFormat } },
00883 { HEADER_EXT_MORE, NULL, { (void *) headerDefaultFormats } }
00884 } ;
00885