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 "manifest.h"
00009 #include "misc.h"
00010 #include "debug.h"
00011 
00020 static /*@only@*/ char * triggertypeFormat(int_32 type, const void * data, 
00021         /*@unused@*/ char * formatPrefix, /*@unused@*/ int padding,
00022         /*@unused@*/ 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 /*@only@*/ char * permsFormat(int_32 type, const void * data, char * formatPrefix,
00047         int padding, /*@unused@*/ int element)
00048                 /*@modifies formatPrefix @*/
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         /*@-formatconst@*/
00060         sprintf(val, formatPrefix, buf);
00061         /*@=formatconst@*/
00062         buf = _free(buf);
00063     }
00064 
00065     return val;
00066 }
00067 
00076 static /*@only@*/ char * fflagsFormat(int_32 type, const void * data, 
00077         char * formatPrefix, int padding, /*@unused@*/ int element)
00078                 /*@modifies formatPrefix @*/
00079 {
00080     char * val;
00081     char buf[15];
00082     int anint = *((int_32 *) data);
00083 
00084     if (type != RPM_INT32_TYPE) {
00085         val = xstrdup(_("(not a number)"));
00086     } else {
00087         buf[0] = '\0';
00088         if (anint & RPMFILE_DOC)
00089             strcat(buf, "d");
00090         if (anint & RPMFILE_CONFIG)
00091             strcat(buf, "c");
00092         if (anint & RPMFILE_SPECFILE)
00093             strcat(buf, "s");
00094         if (anint & RPMFILE_MISSINGOK)
00095             strcat(buf, "m");
00096         if (anint & RPMFILE_NOREPLACE)
00097             strcat(buf, "n");
00098         if (anint & RPMFILE_GHOST)
00099             strcat(buf, "g");
00100 
00101         val = xmalloc(5 + padding);
00102         strcat(formatPrefix, "s");
00103         /*@-formatconst@*/
00104         sprintf(val, formatPrefix, buf);
00105         /*@=formatconst@*/
00106     }
00107 
00108     return val;
00109 }
00110 
00119 static /*@only@*/ char * depflagsFormat(int_32 type, const void * data, 
00120         char * formatPrefix, int padding, /*@unused@*/ int element)
00121                 /*@modifies formatPrefix @*/
00122 {
00123     char * val;
00124     char buf[10];
00125     int anint = *((int_32 *) data);
00126 
00127     if (type != RPM_INT32_TYPE) {
00128         val = xstrdup(_("(not a number)"));
00129     } else {
00130         buf[0] = '\0';
00131 
00132         if (anint & RPMSENSE_LESS) 
00133             strcat(buf, "<");
00134         if (anint & RPMSENSE_GREATER)
00135             strcat(buf, ">");
00136         if (anint & RPMSENSE_EQUAL)
00137             strcat(buf, "=");
00138 
00139         val = xmalloc(5 + padding);
00140         strcat(formatPrefix, "s");
00141         /*@-formatconst@*/
00142         sprintf(val, formatPrefix, buf);
00143         /*@=formatconst@*/
00144     }
00145 
00146     return val;
00147 }
00148 
00157 static int fsnamesTag( /*@unused@*/ Header h, /*@out@*/ int_32 * type,
00158         /*@out@*/ void ** data, /*@out@*/ int_32 * count,
00159         /*@out@*/ int * freeData)
00160                 /*@modifies *type, *data, *count, *freeData @*/
00161 {
00162     const char ** list;
00163 
00164     if (rpmGetFilesystemList(&list, count)) {
00165         return 1;
00166     }
00167 
00168     *type = RPM_STRING_ARRAY_TYPE;
00169     *((const char ***) data) = list;
00170 
00171     *freeData = 0;
00172 
00173     return 0; 
00174 }
00175 
00184 static int instprefixTag(Header h, /*@null@*/ /*@out@*/ rpmTagType * type,
00185         /*@null@*/ /*@out@*/ const void ** data,
00186         /*@null@*/ /*@out@*/ int_32 * count,
00187         /*@null@*/ /*@out@*/ int * freeData)
00188                 /*@modifies *type, *data, *freeData @*/
00189 {
00190     HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00191     HFD_t hfd = headerFreeData;
00192     rpmTagType ipt;
00193     char ** array;
00194 
00195     if (hge(h, RPMTAG_INSTALLPREFIX, type, (void **)data, count)) {
00196         if (freeData) *freeData = 0;
00197         return 0;
00198     } else if (hge(h, RPMTAG_INSTPREFIXES, &ipt, (void **) &array, count)) {
00199         if (data) *data = xstrdup(array[0]);
00200         if (freeData) *freeData = 1;
00201         if (type) *type = RPM_STRING_TYPE;
00202         array = hfd(array, ipt);
00203         return 0;
00204     } 
00205 
00206     return 1;
00207 }
00208 
00217 static int fssizesTag(Header h, /*@out@*/ rpmTagType * type,
00218         /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00219         /*@out@*/ int * freeData)
00220                 /*@modifies *type, *data, *count, *freeData @*/
00221 {
00222     HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00223     const char ** filenames;
00224     int_32 * filesizes;
00225     uint_32 * usages;
00226     int numFiles;
00227 
00228     if (!hge(h, RPMTAG_FILESIZES, NULL, (void **) &filesizes, &numFiles)) {
00229         filesizes = NULL;
00230         numFiles = 0;
00231         filenames = NULL;
00232     } else {
00233         rpmBuildFileList(h, &filenames, &numFiles);
00234     }
00235 
00236     if (rpmGetFilesystemList(NULL, count)) {
00237         return 1;
00238     }
00239 
00240     *type = RPM_INT32_TYPE;
00241     *freeData = 1;
00242 
00243     if (filenames == NULL) {
00244         usages = xcalloc((*count), sizeof(usages));
00245         *data = usages;
00246 
00247         return 0;
00248     }
00249 
00250     if (rpmGetFilesystemUsage(filenames, filesizes, numFiles, &usages, 0))      
00251         return 1;
00252 
00253     *data = usages;
00254 
00255     filenames = _free(filenames);
00256 
00257     return 0;
00258 }
00259 
00268 static int triggercondsTag(Header h, /*@out@*/ rpmTagType * type,
00269         /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00270         /*@out@*/ int * freeData)
00271                 /*@modifies *type, *data, *count, *freeData @*/
00272 {
00273     HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00274     HFD_t hfd = headerFreeData;
00275     rpmTagType tnt, tvt, tst;
00276     int_32 * indices, * flags;
00277     char ** names, ** versions;
00278     int numNames, numScripts;
00279     char ** conds, ** s;
00280     char * item, * flagsStr;
00281     char * chptr;
00282     int i, j;
00283     char buf[5];
00284 
00285     if (!hge(h, RPMTAG_TRIGGERNAME, &tnt, (void **) &names, &numNames)) {
00286         *freeData = 0;
00287         return 0;
00288     }
00289 
00290     (void) hge(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &indices, NULL);
00291     (void) hge(h, RPMTAG_TRIGGERFLAGS, NULL, (void **) &flags, NULL);
00292     (void) hge(h, RPMTAG_TRIGGERVERSION, &tvt, (void **) &versions, NULL);
00293     (void) hge(h, RPMTAG_TRIGGERSCRIPTS, &tst, (void **) &s, &numScripts);
00294     s = hfd(s, tst);
00295 
00296     *freeData = 1;
00297     *data = conds = xmalloc(sizeof(char * ) * numScripts);
00298     *count = numScripts;
00299     *type = RPM_STRING_ARRAY_TYPE;
00300     for (i = 0; i < numScripts; i++) {
00301         chptr = xstrdup("");
00302 
00303         for (j = 0; j < numNames; j++) {
00304             if (indices[j] != i) continue;
00305 
00306             item = xmalloc(strlen(names[j]) + strlen(versions[j]) + 20);
00307             if (flags[j] & RPMSENSE_SENSEMASK) {
00308                 buf[0] = '%', buf[1] = '\0';
00309                 flagsStr = depflagsFormat(RPM_INT32_TYPE, flags, buf, 0, j);
00310                 sprintf(item, "%s %s %s", names[j], flagsStr, versions[j]);
00311                 flagsStr = _free(flagsStr);
00312             } else {
00313                 strcpy(item, names[j]);
00314             }
00315 
00316             chptr = xrealloc(chptr, strlen(chptr) + strlen(item) + 5);
00317             if (*chptr != '\0') strcat(chptr, ", ");
00318             strcat(chptr, item);
00319             item = _free(item);
00320         }
00321 
00322         conds[i] = chptr;
00323     }
00324 
00325     names = hfd(names, tnt);
00326     versions = hfd(versions, tvt);
00327 
00328     return 0;
00329 }
00330 
00339 static int triggertypeTag(Header h, /*@out@*/ rpmTagType * type,
00340         /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00341         /*@out@*/ int * freeData)
00342                 /*@modifies *type, *data, *count, *freeData @*/
00343 {
00344     HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00345     HFD_t hfd = headerFreeData;
00346     rpmTagType tst;
00347     int_32 * indices, * flags;
00348     const char ** conds;
00349     const char ** s;
00350     int i, j;
00351     int numScripts, numNames;
00352 
00353     if (!hge(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &indices, &numNames)) {
00354         *freeData = 0;
00355         return 1;
00356     }
00357 
00358     (void) hge(h, RPMTAG_TRIGGERFLAGS, NULL, (void **) &flags, NULL);
00359     (void) hge(h, RPMTAG_TRIGGERSCRIPTS, &tst, (void **) &s, &numScripts);
00360     s = hfd(s, tst);
00361 
00362     *freeData = 1;
00363     *data = conds = xmalloc(sizeof(char * ) * numScripts);
00364     *count = numScripts;
00365     *type = RPM_STRING_ARRAY_TYPE;
00366     for (i = 0; i < numScripts; i++) {
00367         for (j = 0; j < numNames; j++) {
00368             if (indices[j] != i) continue;
00369 
00370             if (flags[j] & RPMSENSE_TRIGGERIN)
00371                 conds[i] = xstrdup("in");
00372             else if (flags[j] & RPMSENSE_TRIGGERUN)
00373                 conds[i] = xstrdup("un");
00374             else
00375                 conds[i] = xstrdup("postun");
00376             /*@innerbreak@*/ break;
00377         }
00378     }
00379 
00380     return 0;
00381 }
00382 
00391 static int filenamesTag(Header h, /*@out@*/ rpmTagType * type,
00392         /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00393         /*@out@*/ int * freeData)
00394                 /*@modifies *type, *data, *count, *freeData @*/
00395 {
00396     *type = RPM_STRING_ARRAY_TYPE;
00397 
00398     rpmBuildFileList(h, (const char ***) data, count);
00399     *freeData = 1;
00400 
00401     *freeData = 0;      /* XXX WTFO? */
00402 
00403     return 0; 
00404 }
00405 
00406 /* I18N look aside diversions */
00407 
00408 /*@-exportlocal -exportheadervar@*/
00409 int _nl_msg_cat_cntr;   /* XXX GNU gettext voodoo */
00410 /*@=exportlocal =exportheadervar@*/
00411 /*@observer@*/ static const char * language = "LANGUAGE";
00412 
00413 /*@observer@*/ static const char * _macro_i18ndomains =
00414                 "%{?_i18ndomains:%{_i18ndomains}}";
00415 
00425 static int i18nTag(Header h, int_32 tag, /*@out@*/ rpmTagType * type,
00426         /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00427         /*@out@*/ int * freeData)
00428                 /*@modifies *type, *data, *count, *freeData @*/
00429 {
00430     HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00431     char * dstring = rpmExpand(_macro_i18ndomains, NULL);
00432     int rc;
00433 
00434     *type = RPM_STRING_TYPE;
00435     *data = NULL;
00436     *count = 0;
00437     *freeData = 0;
00438 
00439     if (dstring && *dstring) {
00440         char *domain, *de;
00441         const char * langval;
00442         const char * msgkey;
00443         const char * msgid;
00444 
00445         {   const char * tn = tagName(tag);
00446             const char * n;
00447             char * mk;
00448             (void) headerNVR(h, &n, NULL, NULL);
00449             mk = alloca(strlen(n) + strlen(tn) + sizeof("()"));
00450             sprintf(mk, "%s(%s)", n, tn);
00451             msgkey = mk;
00452         }
00453 
00454         /* change to en_US for msgkey -> msgid resolution */
00455         langval = getenv(language);
00456         (void) setenv(language, "en_US", 1);
00457         ++_nl_msg_cat_cntr;
00458 
00459         msgid = NULL;
00460         for (domain = dstring; domain != NULL; domain = de) {
00461             de = strchr(domain, ':');
00462             if (de) *de++ = '\0';
00463             msgid = /*@-unrecog@*/ dgettext(domain, msgkey) /*@=unrecog@*/;
00464             if (msgid != msgkey) break;
00465         }
00466 
00467         /* restore previous environment for msgid -> msgstr resolution */
00468         if (langval)
00469             (void) setenv(language, langval, 1);
00470         else
00471             unsetenv(language);
00472         ++_nl_msg_cat_cntr;
00473 
00474         if (domain && msgid) {
00475             *data = /*@-unrecog@*/ dgettext(domain, msgid) /*@=unrecog@*/;
00476             *data = xstrdup(*data);     /* XXX xstrdup has side effects. */
00477             *count = 1;
00478             *freeData = 1;
00479         }
00480         dstring = _free(dstring);
00481         if (*data)
00482             return 0;
00483     }
00484 
00485     dstring = _free(dstring);
00486 
00487     rc = hge(h, tag, type, (void **)data, count);
00488 
00489     if (rc && (*data) != NULL) {
00490         *data = xstrdup(*data);
00491         *freeData = 1;
00492         return 0;
00493     }
00494 
00495     *freeData = 0;
00496     *data = NULL;
00497     *count = 0;
00498     return 1;
00499 }
00500 
00509 static int summaryTag(Header h, /*@out@*/ rpmTagType * type,
00510         /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00511         /*@out@*/ int * freeData)
00512                 /*@modifies *type, *data, *count, *freeData @*/
00513 {
00514     return i18nTag(h, RPMTAG_SUMMARY, type, data, count, freeData);
00515 }
00516 
00525 static int descriptionTag(Header h, /*@out@*/ rpmTagType * type,
00526         /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00527         /*@out@*/ int * freeData)
00528                 /*@modifies *type, *data, *count, *freeData @*/
00529 {
00530     return i18nTag(h, RPMTAG_DESCRIPTION, type, data, count, freeData);
00531 }
00532 
00541 static int groupTag(Header h, /*@out@*/ rpmTagType * type,
00542         /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00543         /*@out@*/ int * freeData)
00544                 /*@modifies *type, *data, *count, *freeData @*/
00545 {
00546     return i18nTag(h, RPMTAG_GROUP, type, data, count, freeData);
00547 }
00548 
00549 const struct headerSprintfExtension_s rpmHeaderFormats[] = {
00550     { HEADER_EXT_TAG, "RPMTAG_GROUP", { groupTag } },
00551     { HEADER_EXT_TAG, "RPMTAG_DESCRIPTION", { descriptionTag } },
00552     { HEADER_EXT_TAG, "RPMTAG_SUMMARY", { summaryTag } },
00553     { HEADER_EXT_TAG, "RPMTAG_FILENAMES", { filenamesTag } },
00554     { HEADER_EXT_TAG, "RPMTAG_FSSIZES", { fssizesTag } },
00555     { HEADER_EXT_TAG, "RPMTAG_FSNAMES", { fsnamesTag } },
00556     { HEADER_EXT_TAG, "RPMTAG_INSTALLPREFIX", { instprefixTag } },
00557     { HEADER_EXT_TAG, "RPMTAG_TRIGGERCONDS", { triggercondsTag } },
00558     { HEADER_EXT_TAG, "RPMTAG_TRIGGERTYPE", { triggertypeTag } },
00559     { HEADER_EXT_FORMAT, "depflags", { depflagsFormat } },
00560     { HEADER_EXT_FORMAT, "fflags", { fflagsFormat } },
00561     { HEADER_EXT_FORMAT, "perms", { permsFormat } },
00562     { HEADER_EXT_FORMAT, "permissions", { permsFormat } },
00563     { HEADER_EXT_FORMAT, "triggertype", { triggertypeFormat } },
00564     { HEADER_EXT_MORE, NULL, { (void *) headerDefaultFormats } }
00565 } ;

Generated on Wed Mar 13 15:34:47 2002 for rpm by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002