Main Page | Modules | Data Structures | File List | Data Fields | Globals | Related Pages

lib/formats.c

Go to the documentation of this file.
00001 
00005 #include "system.h"
00006 #include <rpmlib.h>
00007 #include <rpmmacro.h>   /* XXX for %_i18ndomains */
00008 #include "rpmpgp.h"
00009 #include "manifest.h"
00010 #include "misc.h"
00011 #include "debug.h"
00012 
00021 static /*@only@*/ char * triggertypeFormat(int_32 type, const void * data, 
00022         /*@unused@*/ char * formatPrefix, /*@unused@*/ int padding,
00023         /*@unused@*/ 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 /*@only@*/ char * permsFormat(int_32 type, const void * data, char * formatPrefix,
00046         int padding, /*@unused@*/ int element)
00047                 /*@modifies formatPrefix @*/
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         /*@-formatconst@*/
00059         sprintf(val, formatPrefix, buf);
00060         /*@=formatconst@*/
00061         buf = _free(buf);
00062     }
00063 
00064     return val;
00065 }
00066 
00075 static /*@only@*/ char * fflagsFormat(int_32 type, const void * data, 
00076         char * formatPrefix, int padding, /*@unused@*/ int element)
00077                 /*@modifies formatPrefix @*/
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         /*@-formatconst@*/
00103         sprintf(val, formatPrefix, buf);
00104         /*@=formatconst@*/
00105     }
00106 
00107     return val;
00108 }
00109 
00118 static /*@only@*/ char * armorFormat(int_32 type, const void * data, 
00119                 /*@unused@*/ 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;     /* XXX check pkt for 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;        /* XXX check pkt for 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         /*@notreached@*/ break;
00151     }
00152 
00153     nt = ((ns + 2) / 3) * 4;
00154     /*@-globs@*/
00155     /* Add additional bytes necessary for eol string(s). */
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     /*@=globs@*/
00163 
00164     nt += 512;  /* XXX slop for armor and crc */
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     /*@-globs@*/
00171     t = stpcpy( stpcpy(t, "-----\nVersion: rpm-"), RPMVERSION);
00172     /*@=globs@*/
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     /*@-branchstate@*/
00190     if (s != data) s = _free(s);
00191     /*@=branchstate@*/
00192 
00193     return val;
00194 }
00195 
00204 static /*@only@*/ char * base64Format(int_32 type, const void * data, 
00205                 /*@unused@*/ 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         /*@-globs@*/
00219         /* Add additional bytes necessary for eol string(s). */
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         /*@=globs@*/
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 /*@only@*/ char * pgppktFormat(int_32 type, const void * data, 
00250         char * formatPrefix, int padding, int element)
00251                 /*@modifies formatPrefix @*/
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 /*@only@*/ char * depflagsFormat(int_32 type, const void * data, 
00273         char * formatPrefix, int padding, /*@unused@*/ int element)
00274                 /*@modifies formatPrefix @*/
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         /*@-formatconst@*/
00295         sprintf(val, formatPrefix, buf);
00296         /*@=formatconst@*/
00297     }
00298 
00299     return val;
00300 }
00301 
00310 static int fsnamesTag( /*@unused@*/ Header h, /*@out@*/ int_32 * type,
00311                 /*@out@*/ void ** data, /*@out@*/ int_32 * count,
00312                 /*@out@*/ int * freeData)
00313         /*@globals fileSystem, internalState @*/
00314         /*@modifies *type, *data, *count, *freeData,
00315                 fileSystem, internalState @*/
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, /*@null@*/ /*@out@*/ rpmTagType * type,
00340         /*@null@*/ /*@out@*/ const void ** data,
00341         /*@null@*/ /*@out@*/ int_32 * count,
00342         /*@null@*/ /*@out@*/ int * freeData)
00343                 /*@modifies *type, *data, *freeData @*/
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, /*@out@*/ rpmTagType * type,
00373                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00374                 /*@out@*/ int * freeData)
00375         /*@globals rpmGlobalMacroContext,
00376                 fileSystem, internalState @*/
00377         /*@modifies *type, *data, *count, *freeData, rpmGlobalMacroContext,
00378                 fileSystem, internalState @*/
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, /*@out@*/ rpmTagType * type,
00427         /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00428         /*@out@*/ int * freeData)
00429                 /*@modifies *type, *data, *count, *freeData @*/
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                 /*@innercontinue@*/ 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, /*@out@*/ rpmTagType * type,
00499         /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00500         /*@out@*/ int * freeData)
00501                 /*@modifies *type, *data, *count, *freeData @*/
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                 /*@innercontinue@*/ 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             /*@innerbreak@*/ break;
00537         }
00538     }
00539 
00540     return 0;
00541 }
00542 
00551 static int filenamesTag(Header h, /*@out@*/ rpmTagType * type,
00552         /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00553         /*@out@*/ int * freeData)
00554                 /*@modifies *type, *data, *count, *freeData @*/
00555 {
00556     *type = RPM_STRING_ARRAY_TYPE;
00557 
00558     rpmBuildFileList(h, (const char ***) data, count);
00559     *freeData = 1;
00560 
00561     *freeData = 0;      /* XXX WTFO? */
00562 
00563     return 0; 
00564 }
00565 
00566 /* I18N look aside diversions */
00567 
00568 /*@-exportlocal -exportheadervar@*/
00569 /*@unchecked@*/
00570 int _nl_msg_cat_cntr;   /* XXX GNU gettext voodoo */
00571 /*@=exportlocal =exportheadervar@*/
00572 /*@observer@*/ /*@unchecked@*/
00573 static const char * language = "LANGUAGE";
00574 
00575 /*@observer@*/ /*@unchecked@*/
00576 static const char * _macro_i18ndomains =
00577                 "%{?_i18ndomains:%{_i18ndomains}}";
00578 
00588 static int i18nTag(Header h, int_32 tag, /*@out@*/ rpmTagType * type,
00589                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00590                 /*@out@*/ int * freeData)
00591         /*@globals rpmGlobalMacroContext @*/
00592         /*@modifies *type, *data, *count, *freeData, rpmGlobalMacroContext @*/
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         /* change to en_US for msgkey -> msgid resolution */
00619         langval = getenv(language);
00620         (void) setenv(language, "en_US", 1);
00621 /*@i@*/ ++_nl_msg_cat_cntr;
00622 
00623         msgid = NULL;
00624         /*@-branchstate@*/
00625         for (domain = dstring; domain != NULL; domain = de) {
00626             de = strchr(domain, ':');
00627             if (de) *de++ = '\0';
00628             msgid = /*@-unrecog@*/ dgettext(domain, msgkey) /*@=unrecog@*/;
00629             if (msgid != msgkey) break;
00630         }
00631         /*@=branchstate@*/
00632 
00633         /* restore previous environment for msgid -> msgstr resolution */
00634         if (langval)
00635             (void) setenv(language, langval, 1);
00636         else
00637             unsetenv(language);
00638 /*@i@*/ ++_nl_msg_cat_cntr;
00639 
00640         if (domain && msgid) {
00641             *data = /*@-unrecog@*/ dgettext(domain, msgid) /*@=unrecog@*/;
00642             *data = xstrdup(*data);     /* XXX xstrdup has side effects. */
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, /*@out@*/ rpmTagType * type,
00676                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00677                 /*@out@*/ int * freeData)
00678         /*@globals rpmGlobalMacroContext @*/
00679         /*@modifies *type, *data, *count, *freeData, rpmGlobalMacroContext @*/
00680 {
00681     return i18nTag(h, RPMTAG_SUMMARY, type, data, count, freeData);
00682 }
00683 
00692 static int descriptionTag(Header h, /*@out@*/ rpmTagType * type,
00693                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00694                 /*@out@*/ int * freeData)
00695         /*@globals rpmGlobalMacroContext @*/
00696         /*@modifies *type, *data, *count, *freeData, rpmGlobalMacroContext @*/
00697 {
00698     return i18nTag(h, RPMTAG_DESCRIPTION, type, data, count, freeData);
00699 }
00700 
00709 static int groupTag(Header h, /*@out@*/ rpmTagType * type,
00710                 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00711                 /*@out@*/ int * freeData)
00712         /*@globals rpmGlobalMacroContext @*/
00713         /*@modifies *type, *data, *count, *freeData, rpmGlobalMacroContext @*/
00714 {
00715     return i18nTag(h, RPMTAG_GROUP, type, data, count, freeData);
00716 }
00717 
00718 /*@-type@*/ /* FIX: cast? */
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 /*@=type@*/

Generated on Thu Apr 29 08:02:20 2004 for rpm by doxygen 1.3.6