Main Page   Modules   Compound List   File List   Compound Members   File Members   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 "misc.h"
00009 #include "debug.h"
00010 
00016 static /*@only@*/ char * permsString(int mode)  /*@*/
00017 {
00018     char * perms = xmalloc(11);
00019 
00020     strcpy(perms, "-----------");
00021    
00022     if (mode & S_ISVTX) perms[10] = 't';
00023 
00024     /*@-unrecog@*/
00025     if (mode & S_IRUSR) perms[1] = 'r';
00026     if (mode & S_IWUSR) perms[2] = 'w';
00027     if (mode & S_IXUSR) perms[3] = 'x';
00028  
00029     if (mode & S_IRGRP) perms[4] = 'r';
00030     if (mode & S_IWGRP) perms[5] = 'w';
00031     if (mode & S_IXGRP) perms[6] = 'x';
00032 
00033     if (mode & S_IROTH) perms[7] = 'r';
00034     if (mode & S_IWOTH) perms[8] = 'w';
00035     if (mode & S_IXOTH) perms[9] = 'x';
00036     /*@=unrecog@*/
00037 
00038     if (mode & S_ISUID) {
00039         if (mode & S_IXUSR) 
00040             perms[3] = 's'; 
00041         else
00042             perms[3] = 'S'; 
00043     }
00044 
00045     if (mode & S_ISGID) {
00046         if (mode & S_IXGRP) 
00047             perms[6] = 's'; 
00048         else
00049             perms[6] = 'S'; 
00050     }
00051 
00052     if (S_ISDIR(mode)) 
00053         perms[0] = 'd';
00054     else if (S_ISLNK(mode)) {
00055         perms[0] = 'l';
00056     }
00057     else if (S_ISFIFO(mode)) 
00058         perms[0] = 'p';
00059     else if (S_ISSOCK(mode)) 
00060         perms[0] = 'l';
00061     else if (S_ISCHR(mode)) {
00062         perms[0] = 'c';
00063     } else if (S_ISBLK(mode)) {
00064         perms[0] = 'b';
00065     }
00066 
00067     return perms;
00068 }
00069 
00078 static /*@only@*/ char * triggertypeFormat(int_32 type, const void * data, 
00079         /*@unused@*/ char * formatPrefix, /*@unused@*/ int padding,
00080         /*@unused@*/ int element)       /*@*/
00081 {
00082     const int_32 * item = data;
00083     char * val;
00084 
00085     if (type != RPM_INT32_TYPE) {
00086         val = xstrdup(_("(not a number)"));
00087     } else if (*item & RPMSENSE_TRIGGERIN) {
00088         val = xstrdup("in");
00089     } else {
00090         val = xstrdup("un");
00091     }
00092 
00093     return val;
00094 }
00095 
00104 static /*@only@*/ char * permsFormat(int_32 type, const void * data, char * formatPrefix,
00105         int padding, /*@unused@*/ int element)
00106                 /*@modifies formatPrefix @*/
00107 {
00108     char * val;
00109     char * buf;
00110 
00111     if (type != RPM_INT32_TYPE) {
00112         val = xstrdup(_("(not a number)"));
00113     } else {
00114         val = xmalloc(15 + padding);
00115         strcat(formatPrefix, "s");
00116         buf = permsString(*((int_32 *) data));
00117         sprintf(val, formatPrefix, buf);
00118         free(buf);
00119     }
00120 
00121     return val;
00122 }
00123 
00132 static /*@only@*/ char * fflagsFormat(int_32 type, const void * data, 
00133         char * formatPrefix, int padding, /*@unused@*/ int element)
00134                 /*@modifies formatPrefix @*/
00135 {
00136     char * val;
00137     char buf[15];
00138     int anint = *((int_32 *) data);
00139 
00140     if (type != RPM_INT32_TYPE) {
00141         val = xstrdup(_("(not a number)"));
00142     } else {
00143         buf[0] = '\0';
00144         if (anint & RPMFILE_DOC)
00145             strcat(buf, "d");
00146         if (anint & RPMFILE_CONFIG)
00147             strcat(buf, "c");
00148         if (anint & RPMFILE_SPECFILE)
00149             strcat(buf, "s");
00150         if (anint & RPMFILE_MISSINGOK)
00151             strcat(buf, "m");
00152         if (anint & RPMFILE_NOREPLACE)
00153             strcat(buf, "n");
00154         if (anint & RPMFILE_GHOST)
00155             strcat(buf, "g");
00156 
00157         val = xmalloc(5 + padding);
00158         strcat(formatPrefix, "s");
00159         sprintf(val, formatPrefix, buf);
00160     }
00161 
00162     return val;
00163 }
00164 
00173 static /*@only@*/ char * depflagsFormat(int_32 type, const void * data, 
00174         char * formatPrefix, int padding, /*@unused@*/ int element)
00175                 /*@modifies formatPrefix @*/
00176 {
00177     char * val;
00178     char buf[10];
00179     int anint = *((int_32 *) data);
00180 
00181     if (type != RPM_INT32_TYPE) {
00182         val = xstrdup(_("(not a number)"));
00183     } else {
00184         buf[0] = '\0';
00185 
00186         if (anint & RPMSENSE_LESS) 
00187             strcat(buf, "<");
00188         if (anint & RPMSENSE_GREATER)
00189             strcat(buf, ">");
00190         if (anint & RPMSENSE_EQUAL)
00191             strcat(buf, "=");
00192 
00193         val = xmalloc(5 + padding);
00194         strcat(formatPrefix, "s");
00195         sprintf(val, formatPrefix, buf);
00196     }
00197 
00198     return val;
00199 }
00200 
00209 static int fsnamesTag( /*@unused@*/ Header h, /*@out@*/ int_32 * type,
00210         /*@out@*/ void ** data, /*@out@*/ int_32 * count,
00211         /*@out@*/ int * freeData)
00212                 /*@modifies *type, *data, *count, *freeData @*/
00213 {
00214     const char ** list;
00215 
00216     if (rpmGetFilesystemList(&list, count)) {
00217         return 1;
00218     }
00219 
00220     *type = RPM_STRING_ARRAY_TYPE;
00221     *((const char ***) data) = list;
00222 
00223     *freeData = 0;
00224 
00225     return 0; 
00226 }
00227 
00236 static int instprefixTag(Header h, /*@out@*/ int_32 * type,
00237         /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00238         /*@out@*/ int * freeData)
00239                 /*@modifies h, *type, *data, *count, *freeData @*/
00240 {
00241     char ** array;
00242 
00243     if (headerGetEntry(h, RPMTAG_INSTALLPREFIX, type, (void **)data, count)) {
00244         *freeData = 0;
00245         return 0;
00246     } else if (headerGetEntry(h, RPMTAG_INSTPREFIXES, NULL, (void **) &array, 
00247                               count)) {
00248         *data = xstrdup(array[0]);
00249         *freeData = 1;
00250         *type = RPM_STRING_TYPE;
00251         free(array);
00252         return 0;
00253     } 
00254 
00255     return 1;
00256 }
00257 
00266 static int fssizesTag(Header h, /*@out@*/ int_32 * type,
00267         /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00268         /*@out@*/ int * freeData)
00269                 /*@modifies h, *type, *data, *count, *freeData @*/
00270 {
00271     const char ** filenames;
00272     int_32 * filesizes;
00273     uint_32 * usages;
00274     int numFiles;
00275 
00276     if (!headerGetEntry(h, RPMTAG_FILESIZES, NULL, (void **) &filesizes, 
00277                        &numFiles)) {
00278         filesizes = NULL;
00279         numFiles = 0;
00280         filenames = NULL;
00281     } else {
00282         rpmBuildFileList(h, &filenames, &numFiles);
00283     }
00284 
00285     if (rpmGetFilesystemList(NULL, count)) {
00286         return 1;
00287     }
00288 
00289     *type = RPM_INT32_TYPE;
00290     *freeData = 1;
00291 
00292     if (filenames == NULL) {
00293         usages = xcalloc((*count), sizeof(usages));
00294         *data = usages;
00295 
00296         return 0;
00297     }
00298 
00299     if (rpmGetFilesystemUsage(filenames, filesizes, numFiles, &usages, 0))      
00300         return 1;
00301 
00302     *data = usages;
00303 
00304     if (filenames) free(filenames);
00305 
00306     return 0;
00307 }
00308 
00317 static int triggercondsTag(Header h, /*@out@*/ int_32 * type,
00318         /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00319         /*@out@*/ int * freeData)
00320                 /*@modifies h, *type, *data, *count, *freeData @*/
00321 {
00322     int_32 * indices, * flags;
00323     char ** names, ** versions;
00324     int numNames, numScripts;
00325     char ** conds, ** s;
00326     char * item, * flagsStr;
00327     char * chptr;
00328     int i, j;
00329     char buf[5];
00330 
00331     if (!headerGetEntry(h, RPMTAG_TRIGGERNAME, NULL, (void **) &names, 
00332                         &numNames)) {
00333         *freeData = 0;
00334         return 0;
00335     }
00336 
00337     headerGetEntry(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &indices, NULL);
00338     headerGetEntry(h, RPMTAG_TRIGGERFLAGS, NULL, (void **) &flags, NULL);
00339     headerGetEntry(h, RPMTAG_TRIGGERVERSION, NULL, (void **) &versions, NULL);
00340     headerGetEntry(h, RPMTAG_TRIGGERSCRIPTS, NULL, (void **) &s, &numScripts);
00341     free(s);
00342 
00343     *freeData = 1;
00344     *data = conds = xmalloc(sizeof(char * ) * numScripts);
00345     *count = numScripts;
00346     *type = RPM_STRING_ARRAY_TYPE;
00347     for (i = 0; i < numScripts; i++) {
00348         chptr = xstrdup("");
00349 
00350         for (j = 0; j < numNames; j++) {
00351             if (indices[j] != i) continue;
00352 
00353             item = xmalloc(strlen(names[j]) + strlen(versions[j]) + 20);
00354             if (flags[j] & RPMSENSE_SENSEMASK) {
00355                 buf[0] = '%', buf[1] = '\0';
00356                 flagsStr = depflagsFormat(RPM_INT32_TYPE, flags, buf,
00357                                           0, j);
00358                 sprintf(item, "%s %s %s", names[j], flagsStr, versions[j]);
00359                 free(flagsStr);
00360             } else {
00361                 strcpy(item, names[j]);
00362             }
00363 
00364             chptr = xrealloc(chptr, strlen(chptr) + strlen(item) + 5);
00365             if (*chptr) strcat(chptr, ", ");
00366             strcat(chptr, item);
00367             free(item);
00368         }
00369 
00370         conds[i] = chptr;
00371     }
00372 
00373     free(names);
00374     free(versions);
00375 
00376     return 0;
00377 }
00378 
00387 static int triggertypeTag(Header h, /*@out@*/ int_32 * type,
00388         /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00389         /*@out@*/ int * freeData)
00390                 /*@modifies h, *type, *data, *count, *freeData @*/
00391 {
00392     int_32 * indices, * flags;
00393     char ** conds, ** s;
00394     int i, j;
00395     int numScripts, numNames;
00396 
00397     if (!headerGetEntry(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &indices, 
00398                         &numNames)) {
00399         *freeData = 0;
00400         return 1;
00401     }
00402 
00403     headerGetEntry(h, RPMTAG_TRIGGERFLAGS, NULL, (void **) &flags, NULL);
00404 
00405     headerGetEntry(h, RPMTAG_TRIGGERSCRIPTS, NULL, (void **) &s, &numScripts);
00406     free(s);
00407 
00408     *freeData = 1;
00409     *data = conds = xmalloc(sizeof(char * ) * numScripts);
00410     *count = numScripts;
00411     *type = RPM_STRING_ARRAY_TYPE;
00412     for (i = 0; i < numScripts; i++) {
00413         for (j = 0; j < numNames; j++) {
00414             if (indices[j] != i) continue;
00415 
00416             if (flags[j] & RPMSENSE_TRIGGERIN)
00417                 conds[i] = xstrdup("in");
00418             else if (flags[j] & RPMSENSE_TRIGGERUN)
00419                 conds[i] = xstrdup("un");
00420             else
00421                 conds[i] = xstrdup("postun");
00422             break;
00423         }
00424     }
00425 
00426     return 0;
00427 }
00428 
00437 static int filenamesTag(Header h, /*@out@*/ int_32 * type,
00438         /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00439         /*@out@*/ int * freeData)
00440                 /*@modifies *type, *data, *count, *freeData @*/
00441 {
00442     *type = RPM_STRING_ARRAY_TYPE;
00443 
00444     rpmBuildFileList(h, (const char ***) data, count);
00445     *freeData = 1;
00446 
00447     *freeData = 0;      /* XXX WTFO? */
00448 
00449     return 0; 
00450 }
00451 
00452 /* I18N look aside diversions */
00453 
00454 int _nl_msg_cat_cntr;   /* XXX GNU gettext voodoo */
00455 static const char * language = "LANGUAGE";
00456 
00457 static char * _macro_i18ndomains = "%{?_i18ndomains:%{_i18ndomains}}";
00458 
00468 static int i18nTag(Header h, int_32 tag, /*@out@*/ int_32 * type,
00469         /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00470         /*@out@*/ int * freeData)
00471                 /*@modifies h, *type, *data, *count, *freeData @*/
00472 {
00473     char * dstring = rpmExpand(_macro_i18ndomains, NULL);
00474     int rc;
00475 
00476     *type = RPM_STRING_TYPE;
00477     *data = NULL;
00478     *count = 0;
00479     *freeData = 0;
00480 
00481     if (dstring && *dstring) {
00482         char *domain, *de;
00483         const char * langval;
00484         const char * msgkey;
00485         const char * msgid;
00486 
00487         {   const char * tn = tagName(tag);
00488             const char * n;
00489             char * mk;
00490             headerNVR(h, &n, NULL, NULL);
00491             mk = alloca(strlen(n) + strlen(tn) + sizeof("()"));
00492             sprintf(mk, "%s(%s)", n, tn);
00493             msgkey = mk;
00494         }
00495 
00496         /* change to en_US for msgkey -> msgid resolution */
00497         langval = getenv(language);
00498         setenv(language, "en_US", 1);
00499         ++_nl_msg_cat_cntr;
00500 
00501         msgid = NULL;
00502         for (domain = dstring; domain != NULL; domain = de) {
00503             de = strchr(domain, ':');
00504             if (de) *de++ = '\0';
00505             msgid = /*@-unrecog@*/ dgettext(domain, msgkey) /*@=unrecog@*/;
00506             if (msgid != msgkey) break;
00507         }
00508 
00509         /* restore previous environment for msgid -> msgstr resolution */
00510         if (langval)
00511             setenv(language, langval, 1);
00512         else
00513             unsetenv(language);
00514         ++_nl_msg_cat_cntr;
00515 
00516         if (domain && msgid) {
00517             *data = /*@-unrecog@*/ dgettext(domain, msgid) /*@=unrecog@*/;
00518             *data = xstrdup(*data);     /* XXX xstrdup has side effects. */
00519             *count = 1;
00520             *freeData = 1;
00521         }
00522         free(dstring); dstring = NULL;
00523         if (*data) {
00524             return 0;
00525         }
00526     }
00527 
00528     if (dstring) free(dstring);
00529 
00530     rc = headerGetEntry(h, tag, type, (void **)data, count);
00531 
00532     if (rc) {
00533         *data = xstrdup(*data);
00534         *freeData = 1;
00535         return 0;
00536     }
00537 
00538     *freeData = 0;
00539     *data = NULL;
00540     *count = 0;
00541     return 1;
00542 }
00543 
00552 static int summaryTag(Header h, /*@out@*/ int_32 * type,
00553         /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00554         /*@out@*/ int * freeData)
00555                 /*@modifies h, *type, *data, *count, *freeData @*/
00556 {
00557     return i18nTag(h, RPMTAG_SUMMARY, type, data, count, freeData);
00558 }
00559 
00568 static int descriptionTag(Header h, /*@out@*/ int_32 * type,
00569         /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00570         /*@out@*/ int * freeData)
00571                 /*@modifies h, *type, *data, *count, *freeData @*/
00572 {
00573     return i18nTag(h, RPMTAG_DESCRIPTION, type, data, count, freeData);
00574 }
00575 
00584 static int groupTag(Header h, /*@out@*/ int_32 * type,
00585         /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
00586         /*@out@*/ int * freeData)
00587                 /*@modifies h, *type, *data, *count, *freeData @*/
00588 {
00589     return i18nTag(h, RPMTAG_GROUP, type, data, count, freeData);
00590 }
00591 
00592 const struct headerSprintfExtension rpmHeaderFormats[] = {
00593     { HEADER_EXT_TAG, "RPMTAG_GROUP", { groupTag } },
00594     { HEADER_EXT_TAG, "RPMTAG_DESCRIPTION", { descriptionTag } },
00595     { HEADER_EXT_TAG, "RPMTAG_SUMMARY", { summaryTag } },
00596     { HEADER_EXT_TAG, "RPMTAG_FILENAMES", { filenamesTag } },
00597     { HEADER_EXT_TAG, "RPMTAG_FSSIZES", { fssizesTag } },
00598     { HEADER_EXT_TAG, "RPMTAG_FSNAMES", { fsnamesTag } },
00599     { HEADER_EXT_TAG, "RPMTAG_INSTALLPREFIX", { instprefixTag } },
00600     { HEADER_EXT_TAG, "RPMTAG_TRIGGERCONDS", { triggercondsTag } },
00601     { HEADER_EXT_TAG, "RPMTAG_TRIGGERTYPE", { triggertypeTag } },
00602     { HEADER_EXT_FORMAT, "depflags", { depflagsFormat } },
00603     { HEADER_EXT_FORMAT, "fflags", { fflagsFormat } },
00604     { HEADER_EXT_FORMAT, "perms", { permsFormat } },
00605     { HEADER_EXT_FORMAT, "permissions", { permsFormat } },
00606     { HEADER_EXT_FORMAT, "triggertype", { triggertypeFormat } },
00607     { HEADER_EXT_MORE, NULL, { (void *) headerDefaultFormats } }
00608 } ;

Generated at Sun Apr 8 18:42:59 2001 for rpm by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000