4 #include <rpmmacro.h> /* XXX for %_i18ndomains */
7 static char * permsString(int mode)
9 char * perms = xmalloc(11);
11 strcpy(perms, "-----------");
13 if (mode & S_ISVTX) perms[10] = 't';
16 if (mode & S_IRUSR) perms[1] = 'r';
17 if (mode & S_IWUSR) perms[2] = 'w';
18 if (mode & S_IXUSR) perms[3] = 'x';
20 if (mode & S_IRGRP) perms[4] = 'r';
21 if (mode & S_IWGRP) perms[5] = 'w';
22 if (mode & S_IXGRP) perms[6] = 'x';
24 if (mode & S_IROTH) perms[7] = 'r';
25 if (mode & S_IWOTH) perms[8] = 'w';
26 if (mode & S_IXOTH) perms[9] = 'x';
45 else if (S_ISLNK(mode)) {
48 else if (S_ISFIFO(mode))
50 else if (S_ISSOCK(mode))
52 else if (S_ISCHR(mode)) {
54 } else if (S_ISBLK(mode)) {
61 static char * triggertypeFormat(int_32 type, const void * data,
62 /*@unused@*/ char * formatPrefix, /*@unused@*/ int padding,
63 /*@unused@*/ int element)
65 const int_32 * item = data;
68 if (type != RPM_INT32_TYPE) {
69 val = xstrdup(_("(not a number)"));
70 } else if (*item & RPMSENSE_TRIGGERIN) {
79 static char * permsFormat(int_32 type, const void * data,
80 char * formatPrefix, int padding, /*@unused@*/ int element)
85 if (type != RPM_INT32_TYPE) {
86 val = xstrdup(_("(not a number)"));
88 val = xmalloc(15 + padding);
89 strcat(formatPrefix, "s");
90 buf = permsString(*((int_32 *) data));
91 sprintf(val, formatPrefix, buf);
98 static char * fflagsFormat(int_32 type, const void * data,
99 char * formatPrefix, int padding, /*@unused@*/ int element)
103 int anint = *((int_32 *) data);
105 if (type != RPM_INT32_TYPE) {
106 val = xstrdup(_("(not a number)"));
109 if (anint & RPMFILE_DOC)
111 if (anint & RPMFILE_CONFIG)
113 if (anint & RPMFILE_SPECFILE)
115 if (anint & RPMFILE_MISSINGOK)
117 if (anint & RPMFILE_NOREPLACE)
119 if (anint & RPMFILE_GHOST)
122 val = xmalloc(5 + padding);
123 strcat(formatPrefix, "s");
124 sprintf(val, formatPrefix, buf);
130 static char * depflagsFormat(int_32 type, const void * data,
131 char * formatPrefix, int padding, /*@unused@*/ int element)
135 int anint = *((int_32 *) data);
137 if (type != RPM_INT32_TYPE) {
138 val = xstrdup(_("(not a number)"));
142 if (anint & RPMSENSE_LESS)
144 if (anint & RPMSENSE_GREATER)
146 if (anint & RPMSENSE_EQUAL)
149 val = xmalloc(5 + padding);
150 strcat(formatPrefix, "s");
151 sprintf(val, formatPrefix, buf);
157 static int fsnamesTag( /*@unused@*/ Header h, /*@out@*/ int_32 * type,
158 /*@out@*/ void ** data, /*@out@*/ int_32 * count,
159 /*@out@*/ int * freeData)
163 if (rpmGetFilesystemList(&list, count)) {
167 *type = RPM_STRING_ARRAY_TYPE;
168 *((const char ***) data) = list;
175 static int instprefixTag(Header h, /*@out@*/ int_32 * type,
176 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
177 /*@out@*/ int * freeData)
181 if (headerGetEntry(h, RPMTAG_INSTALLPREFIX, type, (void **)data, count)) {
184 } else if (headerGetEntry(h, RPMTAG_INSTPREFIXES, NULL, (void **) &array,
186 *data = xstrdup(array[0]);
188 *type = RPM_STRING_TYPE;
196 static int fssizesTag(Header h, /*@out@*/ int_32 * type,
197 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
198 /*@out@*/ int * freeData)
200 const char ** filenames;
205 if (!headerGetEntry(h, RPMTAG_FILESIZES, NULL, (void **) &filesizes,
211 rpmBuildFileList(h, &filenames, &numFiles);
214 if (rpmGetFilesystemList(NULL, count)) {
218 *type = RPM_INT32_TYPE;
221 if (filenames == NULL) {
222 usages = xcalloc((*count), sizeof(usages));
228 if (rpmGetFilesystemUsage(filenames, filesizes, numFiles, &usages, 0))
233 if (filenames) free(filenames);
238 static int triggercondsTag(Header h, /*@out@*/ int_32 * type,
239 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
240 /*@out@*/ int * freeData)
242 int_32 * indices, * flags;
243 char ** names, ** versions;
244 int numNames, numScripts;
246 char * item, * flagsStr;
251 if (!headerGetEntry(h, RPMTAG_TRIGGERNAME, NULL, (void **) &names,
257 headerGetEntry(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &indices, NULL);
258 headerGetEntry(h, RPMTAG_TRIGGERFLAGS, NULL, (void **) &flags, NULL);
259 headerGetEntry(h, RPMTAG_TRIGGERVERSION, NULL, (void **) &versions, NULL);
260 headerGetEntry(h, RPMTAG_TRIGGERSCRIPTS, NULL, (void **) &s, &numScripts);
264 *data = conds = xmalloc(sizeof(char * ) * numScripts);
266 *type = RPM_STRING_ARRAY_TYPE;
267 for (i = 0; i < numScripts; i++) {
270 for (j = 0; j < numNames; j++) {
271 if (indices[j] != i) continue;
273 item = xmalloc(strlen(names[j]) + strlen(versions[j]) + 20);
274 if (flags[j] & RPMSENSE_SENSEMASK) {
275 buf[0] = '%', buf[1] = '\0';
276 flagsStr = depflagsFormat(RPM_INT32_TYPE, flags, buf,
278 sprintf(item, "%s %s %s", names[j], flagsStr, versions[j]);
281 strcpy(item, names[j]);
284 chptr = xrealloc(chptr, strlen(chptr) + strlen(item) + 5);
285 if (*chptr) strcat(chptr, ", ");
299 static int triggertypeTag(Header h, /*@out@*/ int_32 * type,
300 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
301 /*@out@*/ int * freeData)
303 int_32 * indices, * flags;
306 int numScripts, numNames;
308 if (!headerGetEntry(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &indices,
314 headerGetEntry(h, RPMTAG_TRIGGERFLAGS, NULL, (void **) &flags, NULL);
316 headerGetEntry(h, RPMTAG_TRIGGERSCRIPTS, NULL, (void **) &s, &numScripts);
320 *data = conds = xmalloc(sizeof(char * ) * numScripts);
322 *type = RPM_STRING_ARRAY_TYPE;
323 for (i = 0; i < numScripts; i++) {
324 for (j = 0; j < numNames; j++) {
325 if (indices[j] != i) continue;
327 if (flags[j] & RPMSENSE_TRIGGERIN)
328 conds[i] = xstrdup("in");
329 else if (flags[j] & RPMSENSE_TRIGGERUN)
330 conds[i] = xstrdup("un");
332 conds[i] = xstrdup("postun");
340 static int filenamesTag(Header h, /*@out@*/ int_32 * type,
341 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
342 /*@out@*/ int * freeData)
344 *type = RPM_STRING_ARRAY_TYPE;
346 rpmBuildFileList(h, (const char ***) data, count);
349 *freeData = 0; /* XXX WTFO? */
354 /* I18N look aside diversions */
356 int _nl_msg_cat_cntr; /* XXX GNU gettext voodoo */
357 static const char * language = "LANGUAGE";
359 static char * _macro_i18ndomains = "%{?_i18ndomains:%{_i18ndomains}}";
361 static int i18nTag(Header h, int_32 tag, /*@out@*/ int_32 * type,
362 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
363 /*@out@*/ int * freeData)
365 char * dstring = rpmExpand(_macro_i18ndomains, NULL);
368 *type = RPM_STRING_TYPE;
373 if (dstring && *dstring) {
375 const char * langval;
379 { const char * tn = tagName(tag);
382 headerNVR(h, &n, NULL, NULL);
383 mk = alloca(strlen(n) + strlen(tn) + sizeof("()"));
384 sprintf(mk, "%s(%s)", n, tn);
388 /* change to en_US for msgkey -> msgid resolution */
389 langval = getenv(language);
390 setenv(language, "en_US", 1);
394 for (domain = dstring; domain != NULL; domain = de) {
395 de = strchr(domain, ':');
396 if (de) *de++ = '\0';
397 msgid = /*@-unrecog@*/ dgettext(domain, msgkey) /*@=unrecog@*/;
398 if (msgid != msgkey) break;
401 /* restore previous environment for msgid -> msgstr resolution */
403 setenv(language, langval, 1);
408 if (domain && msgid) {
409 *data = xstrdup(/*@-unrecog@*/ dgettext(domain, msgid) /*@=unrecog@*/);
413 xfree(dstring); dstring = NULL;
419 if (dstring) xfree(dstring);
421 rc = headerGetEntry(h, tag, type, (void **)data, count);
424 *data = xstrdup(*data);
435 static int summaryTag(Header h, /*@out@*/ int_32 * type,
436 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
437 /*@out@*/ int * freeData)
439 return i18nTag(h, RPMTAG_SUMMARY, type, data, count, freeData);
442 static int descriptionTag(Header h, /*@out@*/ int_32 * type,
443 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
444 /*@out@*/ int * freeData)
446 return i18nTag(h, RPMTAG_DESCRIPTION, type, data, count, freeData);
449 static int groupTag(Header h, /*@out@*/ int_32 * type,
450 /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
451 /*@out@*/ int * freeData)
453 return i18nTag(h, RPMTAG_GROUP, type, data, count, freeData);
456 const struct headerSprintfExtension rpmHeaderFormats[] = {
457 { HEADER_EXT_TAG, "RPMTAG_GROUP", { groupTag } },
458 { HEADER_EXT_TAG, "RPMTAG_DESCRIPTION", { descriptionTag } },
459 { HEADER_EXT_TAG, "RPMTAG_SUMMARY", { summaryTag } },
460 { HEADER_EXT_TAG, "RPMTAG_FILENAMES", { filenamesTag } },
461 { HEADER_EXT_TAG, "RPMTAG_FSSIZES", { fssizesTag } },
462 { HEADER_EXT_TAG, "RPMTAG_FSNAMES", { fsnamesTag } },
463 { HEADER_EXT_TAG, "RPMTAG_INSTALLPREFIX", { instprefixTag } },
464 { HEADER_EXT_TAG, "RPMTAG_TRIGGERCONDS", { triggercondsTag } },
465 { HEADER_EXT_TAG, "RPMTAG_TRIGGERTYPE", { triggertypeTag } },
466 { HEADER_EXT_FORMAT, "depflags", { depflagsFormat } },
467 { HEADER_EXT_FORMAT, "fflags", { fflagsFormat } },
468 { HEADER_EXT_FORMAT, "perms", { permsFormat } },
469 { HEADER_EXT_FORMAT, "permissions", { permsFormat } },
470 { HEADER_EXT_FORMAT, "triggertype", { triggertypeFormat } },
471 { HEADER_EXT_MORE, NULL, { (void *) headerDefaultFormats } }