8790a962400a6511978712c9055a97decb845ed9
[tools/librpm-tizen.git] / lib / formats.c
1 #include "system.h"
2
3 #include <rpmlib.h>
4 #include "misc.h"
5
6 static char * permsString(int mode)
7 {
8     char * perms = xmalloc(11);
9
10     strcpy(perms, "-----------");
11    
12     if (mode & S_ISVTX) perms[10] = 't';
13
14     /*@-unrecog@*/
15     if (mode & S_IRUSR) perms[1] = 'r';
16     if (mode & S_IWUSR) perms[2] = 'w';
17     if (mode & S_IXUSR) perms[3] = 'x';
18  
19     if (mode & S_IRGRP) perms[4] = 'r';
20     if (mode & S_IWGRP) perms[5] = 'w';
21     if (mode & S_IXGRP) perms[6] = 'x';
22
23     if (mode & S_IROTH) perms[7] = 'r';
24     if (mode & S_IWOTH) perms[8] = 'w';
25     if (mode & S_IXOTH) perms[9] = 'x';
26     /*@=unrecog@*/
27
28     if (mode & S_ISUID) {
29         if (mode & S_IXUSR) 
30             perms[3] = 's'; 
31         else
32             perms[3] = 'S'; 
33     }
34
35     if (mode & S_ISGID) {
36         if (mode & S_IXGRP) 
37             perms[6] = 's'; 
38         else
39             perms[6] = 'S'; 
40     }
41
42     if (S_ISDIR(mode)) 
43         perms[0] = 'd';
44     else if (S_ISLNK(mode)) {
45         perms[0] = 'l';
46     }
47     else if (S_ISFIFO(mode)) 
48         perms[0] = 'p';
49     else if (S_ISSOCK(mode)) 
50         perms[0] = 'l';
51     else if (S_ISCHR(mode)) {
52         perms[0] = 'c';
53     } else if (S_ISBLK(mode)) {
54         perms[0] = 'b';
55     }
56
57     return perms;
58 }
59
60 static char * triggertypeFormat(int_32 type, const void * data, 
61         /*@unused@*/ char * formatPrefix, /*@unused@*/ int padding,
62         /*@unused@*/ int element)
63 {
64     const int_32 * item = data;
65     char * val;
66
67     if (type != RPM_INT32_TYPE) {
68         val = xstrdup(_("(not a number)"));
69     } else if (*item & RPMSENSE_TRIGGERIN) {
70         val = xstrdup("in");
71     } else {
72         val = xstrdup("un");
73     }
74
75     return val;
76 }
77
78 static char * permsFormat(int_32 type, const void * data, 
79                 char * formatPrefix, int padding, /*@unused@*/ int element)
80 {
81     char * val;
82     char * buf;
83
84     if (type != RPM_INT32_TYPE) {
85         val = xstrdup(_("(not a number)"));
86     } else {
87         val = xmalloc(15 + padding);
88         strcat(formatPrefix, "s");
89         buf = permsString(*((int_32 *) data));
90         sprintf(val, formatPrefix, buf);
91         free(buf);
92     }
93
94     return val;
95 }
96
97 static char * fflagsFormat(int_32 type, const void * data, 
98                 char * formatPrefix, int padding, /*@unused@*/ int element)
99 {
100     char * val;
101     char buf[15];
102     int anint = *((int_32 *) data);
103
104     if (type != RPM_INT32_TYPE) {
105         val = xstrdup(_("(not a number)"));
106     } else {
107         buf[0] = '\0';
108         if (anint & RPMFILE_DOC)
109             strcat(buf, "d");
110         if (anint & RPMFILE_CONFIG)
111             strcat(buf, "c");
112         if (anint & RPMFILE_SPECFILE)
113             strcat(buf, "s");
114         if (anint & RPMFILE_MISSINGOK)
115             strcat(buf, "m");
116         if (anint & RPMFILE_NOREPLACE)
117             strcat(buf, "n");
118         if (anint & RPMFILE_GHOST)
119             strcat(buf, "g");
120
121         val = xmalloc(5 + padding);
122         strcat(formatPrefix, "s");
123         sprintf(val, formatPrefix, buf);
124     }
125
126     return val;
127 }
128
129 static char * depflagsFormat(int_32 type, const void * data, 
130                 char * formatPrefix, int padding, /*@unused@*/ int element)
131 {
132     char * val;
133     char buf[10];
134     int anint = *((int_32 *) data);
135
136     if (type != RPM_INT32_TYPE) {
137         val = xstrdup(_("(not a number)"));
138     } else {
139         buf[0] = '\0';
140
141         if (anint & RPMSENSE_LESS) 
142             strcat(buf, "<");
143         if (anint & RPMSENSE_GREATER)
144             strcat(buf, ">");
145         if (anint & RPMSENSE_EQUAL)
146             strcat(buf, "=");
147
148         val = xmalloc(5 + padding);
149         strcat(formatPrefix, "s");
150         sprintf(val, formatPrefix, buf);
151     }
152
153     return val;
154 }
155
156 static int fsnamesTag( /*@unused@*/ Header h, /*@out@*/ int_32 * type,
157         /*@out@*/ void ** data, /*@out@*/ int_32 * count,
158         /*@out@*/ int * freeData)
159 {
160     const char ** list;
161
162     if (rpmGetFilesystemList(&list, count)) {
163         return 1;
164     }
165
166     *type = RPM_STRING_ARRAY_TYPE;
167     *((const char ***) data) = list;
168
169     *freeData = 0;
170
171     return 0; 
172 }
173
174 static int instprefixTag(Header h, /*@out@*/ int_32 * type,
175         /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
176         /*@out@*/ int * freeData)
177 {
178     char ** array;
179
180     if (headerGetEntry(h, RPMTAG_INSTALLPREFIX, type, (void **)data, count)) {
181         *freeData = 0;
182         return 0;
183     } else if (headerGetEntry(h, RPMTAG_INSTPREFIXES, NULL, (void **) &array, 
184                               count)) {
185         *data = xstrdup(array[0]);
186         *freeData = 1;
187         *type = RPM_STRING_TYPE;
188         free(array);
189         return 0;
190     } 
191
192     return 1;
193 }
194
195 static int fssizesTag(Header h, /*@out@*/ int_32 * type,
196         /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
197         /*@out@*/ int * freeData)
198 {
199     const char ** filenames;
200     int_32 * filesizes;
201     uint_32 * usages;
202     int numFiles;
203
204     if (!headerGetEntry(h, RPMTAG_FILESIZES, NULL, (void **) &filesizes, 
205                        &numFiles)) {
206         filesizes = NULL;
207         numFiles = 0;
208         filenames = NULL;
209     } else {
210         rpmBuildFileList(h, &filenames, &numFiles);
211     }
212
213     if (rpmGetFilesystemList(NULL, count)) {
214         return 1;
215     }
216
217     *type = RPM_INT32_TYPE;
218     *freeData = 1;
219
220     if (filenames == NULL) {
221         usages = xcalloc((*count), sizeof(usages));
222         *data = usages;
223
224         return 0;
225     }
226
227     if (rpmGetFilesystemUsage(filenames, filesizes, numFiles, &usages, 0))      
228         return 1;
229
230     *data = usages;
231
232     if (filenames) free(filenames);
233
234     return 0;
235 }
236
237 static int triggercondsTag(Header h, /*@out@*/ int_32 * type,
238         /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
239         /*@out@*/ int * freeData)
240 {
241     int_32 * indices, * flags;
242     char ** names, ** versions;
243     int numNames, numScripts;
244     char ** conds, ** s;
245     char * item, * flagsStr;
246     char * chptr;
247     int i, j;
248     char buf[5];
249
250     if (!headerGetEntry(h, RPMTAG_TRIGGERNAME, NULL, (void **) &names, 
251                         &numNames)) {
252         *freeData = 0;
253         return 0;
254     }
255
256     headerGetEntry(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &indices, NULL);
257     headerGetEntry(h, RPMTAG_TRIGGERFLAGS, NULL, (void **) &flags, NULL);
258     headerGetEntry(h, RPMTAG_TRIGGERVERSION, NULL, (void **) &versions, NULL);
259     headerGetEntry(h, RPMTAG_TRIGGERSCRIPTS, NULL, (void **) &s, &numScripts);
260     free(s);
261
262     *freeData = 1;
263     *data = conds = xmalloc(sizeof(char * ) * numScripts);
264     *count = numScripts;
265     *type = RPM_STRING_ARRAY_TYPE;
266     for (i = 0; i < numScripts; i++) {
267         chptr = xstrdup("");
268
269         for (j = 0; j < numNames; j++) {
270             if (indices[j] != i) continue;
271
272             item = xmalloc(strlen(names[j]) + strlen(versions[j]) + 20);
273             if (flags[j] & RPMSENSE_SENSEMASK) {
274                 buf[0] = '%', buf[1] = '\0';
275                 flagsStr = depflagsFormat(RPM_INT32_TYPE, flags, buf,
276                                           0, j);
277                 sprintf(item, "%s %s %s", names[j], flagsStr, versions[j]);
278                 free(flagsStr);
279             } else {
280                 strcpy(item, names[j]);
281             }
282
283             chptr = xrealloc(chptr, strlen(chptr) + strlen(item) + 5);
284             if (*chptr) strcat(chptr, ", ");
285             strcat(chptr, item);
286             free(item);
287         }
288
289         conds[i] = chptr;
290     }
291
292     free(names);
293     free(versions);
294
295     return 0;
296 }
297
298 static int triggertypeTag(Header h, /*@out@*/ int_32 * type,
299         /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
300         /*@out@*/ int * freeData)
301 {
302     int_32 * indices, * flags;
303     char ** conds, ** s;
304     int i, j;
305     int numScripts, numNames;
306
307     if (!headerGetEntry(h, RPMTAG_TRIGGERINDEX, NULL, (void **) &indices, 
308                         &numNames)) {
309         *freeData = 0;
310         return 1;
311     }
312
313     headerGetEntry(h, RPMTAG_TRIGGERFLAGS, NULL, (void **) &flags, NULL);
314
315     headerGetEntry(h, RPMTAG_TRIGGERSCRIPTS, NULL, (void **) &s, &numScripts);
316     free(s);
317
318     *freeData = 1;
319     *data = conds = xmalloc(sizeof(char * ) * numScripts);
320     *count = numScripts;
321     *type = RPM_STRING_ARRAY_TYPE;
322     for (i = 0; i < numScripts; i++) {
323         for (j = 0; j < numNames; j++) {
324             if (indices[j] != i) continue;
325
326             if (flags[j] & RPMSENSE_TRIGGERIN)
327                 conds[i] = xstrdup("in");
328             else if (flags[j] & RPMSENSE_TRIGGERUN)
329                 conds[i] = xstrdup("un");
330             else
331                 conds[i] = xstrdup("postun");
332             break;
333         }
334     }
335
336     return 0;
337 }
338
339 static int filenamesTag(Header h, /*@out@*/ int_32 * type,
340         /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
341         /*@out@*/ int * freeData)
342 {
343     *type = RPM_STRING_ARRAY_TYPE;
344
345     rpmBuildFileList(h, (const char ***) data, count);
346     *freeData = 1;
347
348     *freeData = 0;      /* XXX WTFO? */
349
350     return 0; 
351 }
352
353 /* I18N look aside diversions */
354
355 char * i18ndomains = NULL;
356
357 int _nl_msg_cat_cntr;   /* XXX GNU gettext voodoo */
358 static const char * language = "LANGUAGE";
359
360 static int i18nTag(Header h, int_32 tag, /*@out@*/ int_32 * type,
361         /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
362         /*@out@*/ int * freeData)
363 {
364     int rc;
365
366     *type = RPM_STRING_TYPE;
367     *data = NULL;
368     *count = 0;
369     *freeData = 0;
370
371     if (i18ndomains) {
372         char * dstring, *domain, *de;
373         const char * langval;
374         const char * msgkey;
375         const char * msgid;
376
377         {   const char * tn = tagName(tag);
378             const char * n;
379             char * mk;
380             headerNVR(h, &n, NULL, NULL);
381             mk = alloca(strlen(n) + strlen(tn) + sizeof("()"));
382             sprintf(mk, "%s(%s)", n, tn);
383             msgkey = mk;
384         }
385
386         /* change to en_US for msgkey -> msgid resolution */
387         langval = getenv(language);
388         setenv(language, "en_US", 1);
389         ++_nl_msg_cat_cntr;
390
391         msgid = NULL;
392         dstring = xstrdup(i18ndomains);
393         for (domain = dstring; domain != NULL; domain = de) {
394             de = strchr(domain, ':');
395             if (de) *de++ = '\0';
396             msgid = /*@-unrecog@*/ dgettext(domain, msgkey) /*@=unrecog@*/;
397             if (msgid != msgkey) break;
398         }
399
400         /* restore previous environment for msgid -> msgstr resolution */
401         if (langval)
402             setenv(language, langval, 1);
403         else
404             unsetenv(language);
405         ++_nl_msg_cat_cntr;
406
407         if (domain && msgid) {
408             *data = xstrdup(/*@-unrecog@*/ dgettext(domain, msgid) /*@=unrecog@*/);
409             *count = 1;
410             *freeData = 1;
411         }
412         xfree(dstring);
413         if (*data) {
414             return 0;
415         }
416     }
417
418     rc = headerGetEntry(h, tag, type, (void **)data, count);
419
420     if (rc) {
421         *data = xstrdup(*data);
422         *freeData = 1;
423         return 0;
424     }
425
426     *freeData = 0;
427     *data = NULL;
428     *count = 0;
429     return 1;
430 }
431
432 static int summaryTag(Header h, /*@out@*/ int_32 * type,
433         /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
434         /*@out@*/ int * freeData)
435 {
436     return i18nTag(h, RPMTAG_SUMMARY, type, data, count, freeData);
437 }
438
439 static int descriptionTag(Header h, /*@out@*/ int_32 * type,
440         /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
441         /*@out@*/ int * freeData)
442 {
443     return i18nTag(h, RPMTAG_DESCRIPTION, type, data, count, freeData);
444 }
445
446 static int groupTag(Header h, /*@out@*/ int_32 * type,
447         /*@out@*/ const void ** data, /*@out@*/ int_32 * count,
448         /*@out@*/ int * freeData)
449 {
450     return i18nTag(h, RPMTAG_GROUP, type, data, count, freeData);
451 }
452
453 const struct headerSprintfExtension rpmHeaderFormats[] = {
454     { HEADER_EXT_TAG, "RPMTAG_GROUP", { groupTag } },
455     { HEADER_EXT_TAG, "RPMTAG_DESCRIPTION", { descriptionTag } },
456     { HEADER_EXT_TAG, "RPMTAG_SUMMARY", { summaryTag } },
457     { HEADER_EXT_TAG, "RPMTAG_FILENAMES", { filenamesTag } },
458     { HEADER_EXT_TAG, "RPMTAG_FSSIZES", { fssizesTag } },
459     { HEADER_EXT_TAG, "RPMTAG_FSNAMES", { fsnamesTag } },
460     { HEADER_EXT_TAG, "RPMTAG_INSTALLPREFIX", { instprefixTag } },
461     { HEADER_EXT_TAG, "RPMTAG_TRIGGERCONDS", { triggercondsTag } },
462     { HEADER_EXT_TAG, "RPMTAG_TRIGGERTYPE", { triggertypeTag } },
463     { HEADER_EXT_FORMAT, "depflags", { depflagsFormat } },
464     { HEADER_EXT_FORMAT, "fflags", { fflagsFormat } },
465     { HEADER_EXT_FORMAT, "perms", { permsFormat } },
466     { HEADER_EXT_FORMAT, "permissions", { permsFormat } },
467     { HEADER_EXT_FORMAT, "triggertype", { triggertypeFormat } },
468     { HEADER_EXT_MORE, NULL, { (void *) headerDefaultFormats } }
469 } ;