00001
00005 #include "system.h"
00006 #include <rpmlib.h>
00007 #include <rpmmacro.h>
00008 #include "misc.h"
00009 #include "debug.h"
00010
00016 static 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
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
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 char * triggertypeFormat(int_32 type, const void * data,
00079 char * formatPrefix, int padding,
00080 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 char * permsFormat(int_32 type, const void * data, char * formatPrefix,
00105 int padding, int element)
00106
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 char * fflagsFormat(int_32 type, const void * data,
00133 char * formatPrefix, int padding, int element)
00134
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 char * depflagsFormat(int_32 type, const void * data,
00174 char * formatPrefix, int padding, int element)
00175
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( Header h, int_32 * type,
00210 void ** data, int_32 * count,
00211 int * freeData)
00212
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, int_32 * type,
00237 const void ** data, int_32 * count,
00238 int * freeData)
00239
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, int_32 * type,
00267 const void ** data, int_32 * count,
00268 int * freeData)
00269
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, int_32 * type,
00318 const void ** data, int_32 * count,
00319 int * freeData)
00320
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, int_32 * type,
00388 const void ** data, int_32 * count,
00389 int * freeData)
00390
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, int_32 * type,
00438 const void ** data, int_32 * count,
00439 int * freeData)
00440
00441 {
00442 *type = RPM_STRING_ARRAY_TYPE;
00443
00444 rpmBuildFileList(h, (const char ***) data, count);
00445 *freeData = 1;
00446
00447 *freeData = 0;
00448
00449 return 0;
00450 }
00451
00452
00453
00454 int _nl_msg_cat_cntr;
00455 static const char * language = "LANGUAGE";
00456
00457 static char * _macro_i18ndomains = "%{?_i18ndomains:%{_i18ndomains}}";
00458
00468 static int i18nTag(Header h, int_32 tag, int_32 * type,
00469 const void ** data, int_32 * count,
00470 int * freeData)
00471
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
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 = dgettext(domain, msgkey) ;
00506 if (msgid != msgkey) break;
00507 }
00508
00509
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 = dgettext(domain, msgid) ;
00518 *data = xstrdup(*data);
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, int_32 * type,
00553 const void ** data, int_32 * count,
00554 int * freeData)
00555
00556 {
00557 return i18nTag(h, RPMTAG_SUMMARY, type, data, count, freeData);
00558 }
00559
00568 static int descriptionTag(Header h, int_32 * type,
00569 const void ** data, int_32 * count,
00570 int * freeData)
00571
00572 {
00573 return i18nTag(h, RPMTAG_DESCRIPTION, type, data, count, freeData);
00574 }
00575
00584 static int groupTag(Header h, int_32 * type,
00585 const void ** data, int_32 * count,
00586 int * freeData)
00587
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 } ;