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         sprintf(val, formatPrefix, buf);
00060         buf = _free(buf);
00061     }
00062 
00063     return val;
00064 }
00065 
00074 static /*@only@*/ char * fflagsFormat(int_32 type, const void * data, 
00075         char * formatPrefix, int padding, /*@unused@*/ int element)
00076                 /*@modifies formatPrefix @*/
00077 {
00078     char * val;
00079     char buf[15];
00080     int anint = *((int_32 *) data);
00081 
00082     if (type != RPM_INT32_TYPE) {
00083         val = xstrdup(_("(not a number)"));
00084     } else {
00085         buf[0] = '\0';
00086         if (anint & RPMFILE_DOC)
00087             strcat(buf, "d");
00088         if (anint & RPMFILE_CONFIG)
00089             strcat(buf, "c");
00090         if (anint & RPMFILE_SPECFILE)
00091             strcat(buf, "s");
00092         if (anint & RPMFILE_MISSINGOK)
00093             strcat(buf, "m");
00094         if (anint & RPMFILE_NOREPLACE)
00095             strcat(buf, "n");
00096         if (anint & RPMFILE_GHOST)
00097             strcat(buf, "g");
00098 
00099         val = xmalloc(5 + padding);
00100         strcat(formatPrefix, "s");
00101         sprintf(val, formatPrefix, buf);
00102     }
00103 
00104     return val;
00105 }
00106 
00115 static /*@only@*/ char * depflagsFormat(int_32 type, const void * data, 
00116         char * formatPrefix, int padding, /*@unused@*/ int element)
00117                 /*@modifies formatPrefix @*/
00118 {
00119     char * val;
00120     char buf[10];
00121     int anint = *((int_32 *) data);
00122 
00123     if (type != RPM_INT32_TYPE) {
00124         val = xstrdup(_("(not a number)"));
00125     } else {
00126         buf[0] = '\0';
00127 
00128         if (anint & RPMSENSE_LESS) 
00129             strcat(buf, "<");
00130         if (anint & RPMSENSE_GREATER)
00131             strcat(buf, ">");
00132         if (anint & RPMSENSE_EQUAL)
00133             strcat(buf, "=");
00134 
00135         val = xmalloc(5 + padding);
00136         strcat(formatPrefix, "s");
00137         sprintf(val, formatPrefix, buf);
00138     }
00139 
00140     return val;
00141 }
00142 
00151 static int fsnamesTag( /*@unused@*/ Header h, /*@out@*/ int_32 * type,
00152         /*@out@*/ void ** data, /*@out@*/ int_32 * count,
00153         /*@out@*/ int * freeData)
00154                 /*@modifies *type, *data, *count, *freeData @*/
00155 {
00156     const char ** list;
00157 
00158     if (rpmGetFilesystemList(&list, count)) {
00159         return 1;
00160     }
00161 
00162     *type = RPM_STRING_ARRAY_TYPE;
00163     *((const char ***) data) = list;
00164 
00165     *freeData = 0;
00166 
00167     return 0; 
00168 }
00169 
00178 static int instprefixTag(Header h, /*@null@*/ /*@out@*/ rpmTagType * type,
00179         /*@null@*/ /*@out@*/ const void ** data,
00180         /*@null@*/ /*@out@*/ int_32 * count,
00181         /*@null@*/ /*@out@*/ int * freeData)
00182                 /*@modifies *type, *data, *freeData @*/
00183 {
00184     HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00185     HFD_t hfd = headerFreeData;
00186     rpmTagType ipt;
00187     char ** array;
00188 
00189     if (hge(h, RPMTAG_INSTALLPREFIX, type, (void **)data, count)) {
00190         if (freeData) *freeData = 0;
00191         return 0;
00192     } else if (hge(h, RPMTAG_INSTPREFIXES, &ipt, (void **) &array, count)) {
00193         if (data) *data = xstrdup(array[0]);
00194         if (freeData) *freeData = 1;
00195         if (type) *type = RPM_STRING_TYPE;
00196         array = hfd(array, ipt);
00197         return 0;
00198     } 
00199 
00200     return 1;
00201 }
00202 
00211 static int fssizesTag(Header h, /*@out@*/ rpmTagType * type,
00212         /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00213         /*@out@*/ int * freeData)
00214                 /*@modifies *type, *data, *count, *freeData @*/
00215 {
00216     HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00217     const char ** filenames;
00218     int_32 * filesizes;
00219     uint_32 * usages;
00220     int numFiles;
00221 
00222     if (!hge(h, RPMTAG_FILESIZES, NULL, (void **) &filesizes, &numFiles)) {
00223         filesizes = NULL;
00224         numFiles = 0;
00225         filenames = NULL;
00226     } else {
00227         rpmBuildFileList(h, &filenames, &numFiles);
00228     }
00229 
00230     if (rpmGetFilesystemList(NULL, count)) {
00231         return 1;
00232     }
00233 
00234     *type = RPM_INT32_TYPE;
00235     *freeData = 1;
00236 
00237     if (filenames == NULL) {
00238         usages = xcalloc((*count), sizeof(usages));
00239         *data = usages;
00240 
00241         return 0;
00242     }
00243 
00244     if (rpmGetFilesystemUsage(filenames, filesizes, numFiles, &usages, 0))      
00245         return 1;
00246 
00247     *data = usages;
00248 
00249     filenames = _free(filenames);
00250 
00251     return 0;
00252 }
00253 
00262 static int triggercondsTag(Header h, /*@out@*/ rpmTagType * type,
00263         /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00264         /*@out@*/ int * freeData)
00265                 /*@modifies *type, *data, *count, *freeData @*/
00266 {
00267     HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00268     HFD_t hfd = headerFreeData;
00269     rpmTagType tnt, tvt, tst;
00270     int_32 * indices, * flags;
00271     char ** names, ** versions;
00272     int numNames, numScripts;
00273     char ** conds, ** s;
00274     char * item, * flagsStr;
00275     char * chptr;
00276     int i, j;
00277     char buf[5];
00278 
00279     if (!hge(h, RPMTAG_TRIGGERNAME, &tnt, (void **) &names, &numNames)) {
00280         *freeData = 0;
00281         return 0;
00282     }
00283 
00284     (void) hge(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &indices, NULL);
00285     (void) hge(h, RPMTAG_TRIGGERFLAGS, NULL, (void **) &flags, NULL);
00286     (void) hge(h, RPMTAG_TRIGGERVERSION, &tvt, (void **) &versions, NULL);
00287     (void) hge(h, RPMTAG_TRIGGERSCRIPTS, &tst, (void **) &s, &numScripts);
00288     s = hfd(s, tst);
00289 
00290     *freeData = 1;
00291     *data = conds = xmalloc(sizeof(char * ) * numScripts);
00292     *count = numScripts;
00293     *type = RPM_STRING_ARRAY_TYPE;
00294     for (i = 0; i < numScripts; i++) {
00295         chptr = xstrdup("");
00296 
00297         for (j = 0; j < numNames; j++) {
00298             if (indices[j] != i) continue;
00299 
00300             item = xmalloc(strlen(names[j]) + strlen(versions[j]) + 20);
00301             if (flags[j] & RPMSENSE_SENSEMASK) {
00302                 buf[0] = '%', buf[1] = '\0';
00303                 flagsStr = depflagsFormat(RPM_INT32_TYPE, flags, buf, 0, j);
00304                 sprintf(item, "%s %s %s", names[j], flagsStr, versions[j]);
00305                 flagsStr = _free(flagsStr);
00306             } else {
00307                 strcpy(item, names[j]);
00308             }
00309 
00310             chptr = xrealloc(chptr, strlen(chptr) + strlen(item) + 5);
00311             if (*chptr != '\0') strcat(chptr, ", ");
00312             strcat(chptr, item);
00313             item = _free(item);
00314         }
00315 
00316         conds[i] = chptr;
00317     }
00318 
00319     names = hfd(names, tnt);
00320     versions = hfd(versions, tvt);
00321 
00322     return 0;
00323 }
00324 
00333 static int triggertypeTag(Header h, /*@out@*/ rpmTagType * type,
00334         /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00335         /*@out@*/ int * freeData)
00336                 /*@modifies *type, *data, *count, *freeData @*/
00337 {
00338     HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00339     HFD_t hfd = headerFreeData;
00340     rpmTagType tst;
00341     int_32 * indices, * flags;
00342     const char ** conds;
00343     const char ** s;
00344     int i, j;
00345     int numScripts, numNames;
00346 
00347     if (!hge(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &indices, &numNames)) {
00348         *freeData = 0;
00349         return 1;
00350     }
00351 
00352     (void) hge(h, RPMTAG_TRIGGERFLAGS, NULL, (void **) &flags, NULL);
00353     (void) hge(h, RPMTAG_TRIGGERSCRIPTS, &tst, (void **) &s, &numScripts);
00354     s = hfd(s, tst);
00355 
00356     *freeData = 1;
00357     *data = conds = xmalloc(sizeof(char * ) * numScripts);
00358     *count = numScripts;
00359     *type = RPM_STRING_ARRAY_TYPE;
00360     for (i = 0; i < numScripts; i++) {
00361         for (j = 0; j < numNames; j++) {
00362             if (indices[j] != i) continue;
00363 
00364             if (flags[j] & RPMSENSE_TRIGGERIN)
00365                 conds[i] = xstrdup("in");
00366             else if (flags[j] & RPMSENSE_TRIGGERUN)
00367                 conds[i] = xstrdup("un");
00368             else
00369                 conds[i] = xstrdup("postun");
00370             /*@innerbreak@*/ break;
00371         }
00372     }
00373 
00374     return 0;
00375 }
00376 
00385 static int filenamesTag(Header h, /*@out@*/ rpmTagType * type,
00386         /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00387         /*@out@*/ int * freeData)
00388                 /*@modifies *type, *data, *count, *freeData @*/
00389 {
00390     *type = RPM_STRING_ARRAY_TYPE;
00391 
00392     rpmBuildFileList(h, (const char ***) data, count);
00393     *freeData = 1;
00394 
00395     *freeData = 0;      /* XXX WTFO? */
00396 
00397     return 0; 
00398 }
00399 
00400 /* I18N look aside diversions */
00401 
00402 /*@-exportlocal -exportheadervar@*/
00403 int _nl_msg_cat_cntr;   /* XXX GNU gettext voodoo */
00404 /*@=exportlocal =exportheadervar@*/
00405 /*@observer@*/ static const char * language = "LANGUAGE";
00406 
00407 /*@observer@*/ static const char * _macro_i18ndomains =
00408                 "%{?_i18ndomains:%{_i18ndomains}}";
00409 
00419 static int i18nTag(Header h, int_32 tag, /*@out@*/ rpmTagType * type,
00420         /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00421         /*@out@*/ int * freeData)
00422                 /*@modifies *type, *data, *count, *freeData @*/
00423 {
00424     HGE_t hge = (HGE_t)headerGetEntryMinMemory;
00425     char * dstring = rpmExpand(_macro_i18ndomains, NULL);
00426     int rc;
00427 
00428     *type = RPM_STRING_TYPE;
00429     *data = NULL;
00430     *count = 0;
00431     *freeData = 0;
00432 
00433     if (dstring && *dstring) {
00434         char *domain, *de;
00435         const char * langval;
00436         const char * msgkey;
00437         const char * msgid;
00438 
00439         {   const char * tn = tagName(tag);
00440             const char * n;
00441             char * mk;
00442             (void) headerNVR(h, &n, NULL, NULL);
00443             mk = alloca(strlen(n) + strlen(tn) + sizeof("()"));
00444             sprintf(mk, "%s(%s)", n, tn);
00445             msgkey = mk;
00446         }
00447 
00448         /* change to en_US for msgkey -> msgid resolution */
00449         langval = getenv(language);
00450         (void) setenv(language, "en_US", 1);
00451         ++_nl_msg_cat_cntr;
00452 
00453         msgid = NULL;
00454         for (domain = dstring; domain != NULL; domain = de) {
00455             de = strchr(domain, ':');
00456             if (de) *de++ = '\0';
00457             msgid = /*@-unrecog@*/ dgettext(domain, msgkey) /*@=unrecog@*/;
00458             if (msgid != msgkey) break;
00459         }
00460 
00461         /* restore previous environment for msgid -> msgstr resolution */
00462         if (langval)
00463             (void) setenv(language, langval, 1);
00464         else
00465             unsetenv(language);
00466         ++_nl_msg_cat_cntr;
00467 
00468         if (domain && msgid) {
00469             *data = /*@-unrecog@*/ dgettext(domain, msgid) /*@=unrecog@*/;
00470             *data = xstrdup(*data);     /* XXX xstrdup has side effects. */
00471             *count = 1;
00472             *freeData = 1;
00473         }
00474         dstring = _free(dstring);
00475         if (*data)
00476             return 0;
00477     }
00478 
00479     dstring = _free(dstring);
00480 
00481     rc = hge(h, tag, type, (void **)data, count);
00482 
00483     if (rc) {
00484         *data = xstrdup(*data);
00485         *freeData = 1;
00486         return 0;
00487     }
00488 
00489     *freeData = 0;
00490     *data = NULL;
00491     *count = 0;
00492     return 1;
00493 }
00494 
00503 static int summaryTag(Header h, /*@out@*/ rpmTagType * type,
00504         /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00505         /*@out@*/ int * freeData)
00506                 /*@modifies *type, *data, *count, *freeData @*/
00507 {
00508     return i18nTag(h, RPMTAG_SUMMARY, type, data, count, freeData);
00509 }
00510 
00519 static int descriptionTag(Header h, /*@out@*/ rpmTagType * type,
00520         /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00521         /*@out@*/ int * freeData)
00522                 /*@modifies *type, *data, *count, *freeData @*/
00523 {
00524     return i18nTag(h, RPMTAG_DESCRIPTION, type, data, count, freeData);
00525 }
00526 
00535 static int groupTag(Header h, /*@out@*/ rpmTagType * type,
00536         /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00537         /*@out@*/ int * freeData)
00538                 /*@modifies *type, *data, *count, *freeData @*/
00539 {
00540     return i18nTag(h, RPMTAG_GROUP, type, data, count, freeData);
00541 }
00542 
00543 const struct headerSprintfExtension_s rpmHeaderFormats[] = {
00544     { HEADER_EXT_TAG, "RPMTAG_GROUP", { groupTag } },
00545     { HEADER_EXT_TAG, "RPMTAG_DESCRIPTION", { descriptionTag } },
00546     { HEADER_EXT_TAG, "RPMTAG_SUMMARY", { summaryTag } },
00547     { HEADER_EXT_TAG, "RPMTAG_FILENAMES", { filenamesTag } },
00548     { HEADER_EXT_TAG, "RPMTAG_FSSIZES", { fssizesTag } },
00549     { HEADER_EXT_TAG, "RPMTAG_FSNAMES", { fsnamesTag } },
00550     { HEADER_EXT_TAG, "RPMTAG_INSTALLPREFIX", { instprefixTag } },
00551     { HEADER_EXT_TAG, "RPMTAG_TRIGGERCONDS", { triggercondsTag } },
00552     { HEADER_EXT_TAG, "RPMTAG_TRIGGERTYPE", { triggertypeTag } },
00553     { HEADER_EXT_FORMAT, "depflags", { depflagsFormat } },
00554     { HEADER_EXT_FORMAT, "fflags", { fflagsFormat } },
00555     { HEADER_EXT_FORMAT, "perms", { permsFormat } },
00556     { HEADER_EXT_FORMAT, "permissions", { permsFormat } },
00557     { HEADER_EXT_FORMAT, "triggertype", { triggertypeFormat } },
00558     { HEADER_EXT_MORE, NULL, { (void *) headerDefaultFormats } }
00559 } ;

Generated at Thu Sep 6 11:32:28 2001 for rpm by doxygen1.2.8.1 written by Dimitri van Heesch, © 1997-2001