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         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, /*@out@*/ int_32 * type,
00179         /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00180         /*@out@*/ int * freeData)
00181                 /*@modifies h, *type, *data, *count, *freeData @*/
00182 {
00183     char ** array;
00184 
00185     if (headerGetEntry(h, RPMTAG_INSTALLPREFIX, type, (void **)data, count)) {
00186         *freeData = 0;
00187         return 0;
00188     } else if (headerGetEntry(h, RPMTAG_INSTPREFIXES, NULL, (void **) &array, 
00189                               count)) {
00190         *data = xstrdup(array[0]);
00191         *freeData = 1;
00192         *type = RPM_STRING_TYPE;
00193         free(array);
00194         return 0;
00195     } 
00196 
00197     return 1;
00198 }
00199 
00208 static int fssizesTag(Header h, /*@out@*/ int_32 * type,
00209         /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00210         /*@out@*/ int * freeData)
00211                 /*@modifies h, *type, *data, *count, *freeData @*/
00212 {
00213     const char ** filenames;
00214     int_32 * filesizes;
00215     uint_32 * usages;
00216     int numFiles;
00217 
00218     if (!headerGetEntry(h, RPMTAG_FILESIZES, NULL, (void **) &filesizes, 
00219                        &numFiles)) {
00220         filesizes = NULL;
00221         numFiles = 0;
00222         filenames = NULL;
00223     } else {
00224         rpmBuildFileList(h, &filenames, &numFiles);
00225     }
00226 
00227     if (rpmGetFilesystemList(NULL, count)) {
00228         return 1;
00229     }
00230 
00231     *type = RPM_INT32_TYPE;
00232     *freeData = 1;
00233 
00234     if (filenames == NULL) {
00235         usages = xcalloc((*count), sizeof(usages));
00236         *data = usages;
00237 
00238         return 0;
00239     }
00240 
00241     if (rpmGetFilesystemUsage(filenames, filesizes, numFiles, &usages, 0))      
00242         return 1;
00243 
00244     *data = usages;
00245 
00246     if (filenames) free(filenames);
00247 
00248     return 0;
00249 }
00250 
00259 static int triggercondsTag(Header h, /*@out@*/ int_32 * type,
00260         /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00261         /*@out@*/ int * freeData)
00262                 /*@modifies h, *type, *data, *count, *freeData @*/
00263 {
00264     int_32 * indices, * flags;
00265     char ** names, ** versions;
00266     int numNames, numScripts;
00267     char ** conds, ** s;
00268     char * item, * flagsStr;
00269     char * chptr;
00270     int i, j;
00271     char buf[5];
00272 
00273     if (!headerGetEntry(h, RPMTAG_TRIGGERNAME, NULL, (void **) &names, 
00274                         &numNames)) {
00275         *freeData = 0;
00276         return 0;
00277     }
00278 
00279     headerGetEntry(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &indices, NULL);
00280     headerGetEntry(h, RPMTAG_TRIGGERFLAGS, NULL, (void **) &flags, NULL);
00281     headerGetEntry(h, RPMTAG_TRIGGERVERSION, NULL, (void **) &versions, NULL);
00282     headerGetEntry(h, RPMTAG_TRIGGERSCRIPTS, NULL, (void **) &s, &numScripts);
00283     free(s);
00284 
00285     *freeData = 1;
00286     *data = conds = xmalloc(sizeof(char * ) * numScripts);
00287     *count = numScripts;
00288     *type = RPM_STRING_ARRAY_TYPE;
00289     for (i = 0; i < numScripts; i++) {
00290         chptr = xstrdup("");
00291 
00292         for (j = 0; j < numNames; j++) {
00293             if (indices[j] != i) continue;
00294 
00295             item = xmalloc(strlen(names[j]) + strlen(versions[j]) + 20);
00296             if (flags[j] & RPMSENSE_SENSEMASK) {
00297                 buf[0] = '%', buf[1] = '\0';
00298                 flagsStr = depflagsFormat(RPM_INT32_TYPE, flags, buf,
00299                                           0, j);
00300                 sprintf(item, "%s %s %s", names[j], flagsStr, versions[j]);
00301                 free(flagsStr);
00302             } else {
00303                 strcpy(item, names[j]);
00304             }
00305 
00306             chptr = xrealloc(chptr, strlen(chptr) + strlen(item) + 5);
00307             if (*chptr) strcat(chptr, ", ");
00308             strcat(chptr, item);
00309             free(item);
00310         }
00311 
00312         conds[i] = chptr;
00313     }
00314 
00315     free(names);
00316     free(versions);
00317 
00318     return 0;
00319 }
00320 
00329 static int triggertypeTag(Header h, /*@out@*/ int_32 * type,
00330         /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00331         /*@out@*/ int * freeData)
00332                 /*@modifies h, *type, *data, *count, *freeData @*/
00333 {
00334     int_32 * indices, * flags;
00335     char ** conds, ** s;
00336     int i, j;
00337     int numScripts, numNames;
00338 
00339     if (!headerGetEntry(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &indices, 
00340                         &numNames)) {
00341         *freeData = 0;
00342         return 1;
00343     }
00344 
00345     headerGetEntry(h, RPMTAG_TRIGGERFLAGS, NULL, (void **) &flags, NULL);
00346 
00347     headerGetEntry(h, RPMTAG_TRIGGERSCRIPTS, NULL, (void **) &s, &numScripts);
00348     free(s);
00349 
00350     *freeData = 1;
00351     *data = conds = xmalloc(sizeof(char * ) * numScripts);
00352     *count = numScripts;
00353     *type = RPM_STRING_ARRAY_TYPE;
00354     for (i = 0; i < numScripts; i++) {
00355         for (j = 0; j < numNames; j++) {
00356             if (indices[j] != i) continue;
00357 
00358             if (flags[j] & RPMSENSE_TRIGGERIN)
00359                 conds[i] = xstrdup("in");
00360             else if (flags[j] & RPMSENSE_TRIGGERUN)
00361                 conds[i] = xstrdup("un");
00362             else
00363                 conds[i] = xstrdup("postun");
00364             break;
00365         }
00366     }
00367 
00368     return 0;
00369 }
00370 
00379 static int filenamesTag(Header h, /*@out@*/ int_32 * type,
00380         /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00381         /*@out@*/ int * freeData)
00382                 /*@modifies *type, *data, *count, *freeData @*/
00383 {
00384     *type = RPM_STRING_ARRAY_TYPE;
00385 
00386     rpmBuildFileList(h, (const char ***) data, count);
00387     *freeData = 1;
00388 
00389     *freeData = 0;      /* XXX WTFO? */
00390 
00391     return 0; 
00392 }
00393 
00394 /* I18N look aside diversions */
00395 
00396 int _nl_msg_cat_cntr;   /* XXX GNU gettext voodoo */
00397 static const char * language = "LANGUAGE";
00398 
00399 static char * _macro_i18ndomains = "%{?_i18ndomains:%{_i18ndomains}}";
00400 
00410 static int i18nTag(Header h, int_32 tag, /*@out@*/ int_32 * type,
00411         /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00412         /*@out@*/ int * freeData)
00413                 /*@modifies h, *type, *data, *count, *freeData @*/
00414 {
00415     char * dstring = rpmExpand(_macro_i18ndomains, NULL);
00416     int rc;
00417 
00418     *type = RPM_STRING_TYPE;
00419     *data = NULL;
00420     *count = 0;
00421     *freeData = 0;
00422 
00423     if (dstring && *dstring) {
00424         char *domain, *de;
00425         const char * langval;
00426         const char * msgkey;
00427         const char * msgid;
00428 
00429         {   const char * tn = tagName(tag);
00430             const char * n;
00431             char * mk;
00432             headerNVR(h, &n, NULL, NULL);
00433             mk = alloca(strlen(n) + strlen(tn) + sizeof("()"));
00434             sprintf(mk, "%s(%s)", n, tn);
00435             msgkey = mk;
00436         }
00437 
00438         /* change to en_US for msgkey -> msgid resolution */
00439         langval = getenv(language);
00440         setenv(language, "en_US", 1);
00441         ++_nl_msg_cat_cntr;
00442 
00443         msgid = NULL;
00444         for (domain = dstring; domain != NULL; domain = de) {
00445             de = strchr(domain, ':');
00446             if (de) *de++ = '\0';
00447             msgid = /*@-unrecog@*/ dgettext(domain, msgkey) /*@=unrecog@*/;
00448             if (msgid != msgkey) break;
00449         }
00450 
00451         /* restore previous environment for msgid -> msgstr resolution */
00452         if (langval)
00453             setenv(language, langval, 1);
00454         else
00455             unsetenv(language);
00456         ++_nl_msg_cat_cntr;
00457 
00458         if (domain && msgid) {
00459             *data = /*@-unrecog@*/ dgettext(domain, msgid) /*@=unrecog@*/;
00460             *data = xstrdup(*data);     /* XXX xstrdup has side effects. */
00461             *count = 1;
00462             *freeData = 1;
00463         }
00464         free(dstring); dstring = NULL;
00465         if (*data) {
00466             return 0;
00467         }
00468     }
00469 
00470     if (dstring) free(dstring);
00471 
00472     rc = headerGetEntry(h, tag, type, (void **)data, count);
00473 
00474     if (rc) {
00475         *data = xstrdup(*data);
00476         *freeData = 1;
00477         return 0;
00478     }
00479 
00480     *freeData = 0;
00481     *data = NULL;
00482     *count = 0;
00483     return 1;
00484 }
00485 
00494 static int summaryTag(Header h, /*@out@*/ int_32 * type,
00495         /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00496         /*@out@*/ int * freeData)
00497                 /*@modifies h, *type, *data, *count, *freeData @*/
00498 {
00499     return i18nTag(h, RPMTAG_SUMMARY, type, data, count, freeData);
00500 }
00501 
00510 static int descriptionTag(Header h, /*@out@*/ int_32 * type,
00511         /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00512         /*@out@*/ int * freeData)
00513                 /*@modifies h, *type, *data, *count, *freeData @*/
00514 {
00515     return i18nTag(h, RPMTAG_DESCRIPTION, type, data, count, freeData);
00516 }
00517 
00526 static int groupTag(Header h, /*@out@*/ int_32 * type,
00527         /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00528         /*@out@*/ int * freeData)
00529                 /*@modifies h, *type, *data, *count, *freeData @*/
00530 {
00531     return i18nTag(h, RPMTAG_GROUP, type, data, count, freeData);
00532 }
00533 
00534 const struct headerSprintfExtension rpmHeaderFormats[] = {
00535     { HEADER_EXT_TAG, "RPMTAG_GROUP", { groupTag } },
00536     { HEADER_EXT_TAG, "RPMTAG_DESCRIPTION", { descriptionTag } },
00537     { HEADER_EXT_TAG, "RPMTAG_SUMMARY", { summaryTag } },
00538     { HEADER_EXT_TAG, "RPMTAG_FILENAMES", { filenamesTag } },
00539     { HEADER_EXT_TAG, "RPMTAG_FSSIZES", { fssizesTag } },
00540     { HEADER_EXT_TAG, "RPMTAG_FSNAMES", { fsnamesTag } },
00541     { HEADER_EXT_TAG, "RPMTAG_INSTALLPREFIX", { instprefixTag } },
00542     { HEADER_EXT_TAG, "RPMTAG_TRIGGERCONDS", { triggercondsTag } },
00543     { HEADER_EXT_TAG, "RPMTAG_TRIGGERTYPE", { triggertypeTag } },
00544     { HEADER_EXT_FORMAT, "depflags", { depflagsFormat } },
00545     { HEADER_EXT_FORMAT, "fflags", { fflagsFormat } },
00546     { HEADER_EXT_FORMAT, "perms", { permsFormat } },
00547     { HEADER_EXT_FORMAT, "permissions", { permsFormat } },
00548     { HEADER_EXT_FORMAT, "triggertype", { triggertypeFormat } },
00549     { HEADER_EXT_MORE, NULL, { (void *) headerDefaultFormats } }
00550 } ;

Generated at Thu Apr 19 15:29:42 2001 for rpm by doxygen1.2.6-20010408 written by Dimitri van Heesch, © 1997-2001