Factor -type problems into explicit code annotations.
[platform/upstream/rpm.git] / lib / manifest.c
1 /** \ingroup rpmcli
2  * \file lib/manifest.c
3  */
4
5 #include "system.h"
6
7 #include <rpmio_internal.h>
8 #include <rpmlib.h>
9
10 #include "stringbuf.h"
11 #include "manifest.h"
12 #include "misc.h"
13 #include "debug.h"
14
15 /*@access StringBuf @*/
16
17 char * rpmPermsString(int mode)
18 {
19     char *perms = xstrdup("----------");
20    
21     if (S_ISDIR(mode)) 
22         perms[0] = 'd';
23     else if (S_ISLNK(mode))
24         perms[0] = 'l';
25     else if (S_ISFIFO(mode)) 
26         perms[0] = 'p';
27     else if (S_ISSOCK(mode)) 
28         perms[0] = 's';
29     else if (S_ISCHR(mode))
30         perms[0] = 'c';
31     else if (S_ISBLK(mode))
32         perms[0] = 'b';
33
34     /*@-unrecog@*/
35     if (mode & S_IRUSR) perms[1] = 'r';
36     if (mode & S_IWUSR) perms[2] = 'w';
37     if (mode & S_IXUSR) perms[3] = 'x';
38  
39     if (mode & S_IRGRP) perms[4] = 'r';
40     if (mode & S_IWGRP) perms[5] = 'w';
41     if (mode & S_IXGRP) perms[6] = 'x';
42
43     if (mode & S_IROTH) perms[7] = 'r';
44     if (mode & S_IWOTH) perms[8] = 'w';
45     if (mode & S_IXOTH) perms[9] = 'x';
46
47     if (mode & S_ISUID)
48         perms[3] = ((mode & S_IXUSR) ? 's' : 'S'); 
49
50     if (mode & S_ISGID)
51         perms[6] = ((mode & S_IXGRP) ? 's' : 'S'); 
52
53     if (mode & S_ISVTX)
54         perms[9] = ((mode & S_IXOTH) ? 't' : 'T');
55     /*@=unrecog@*/
56
57     return perms;
58 }
59
60 /**@todo Infinite loops through manifest files exist, operator error for now. */
61 int rpmReadPackageManifest(FD_t fd, int * argcPtr, const char *** argvPtr)
62 {
63     StringBuf sb = newStringBuf();
64     char * s = NULL;
65     char * se;
66     int ac = 0;
67     const char ** av = NULL;
68     int argc = (argcPtr ? *argcPtr : 0);
69     const char ** argv = (argvPtr ? *argvPtr : NULL);
70     /*@-type@*/ /* FIX: cast? */
71     FILE * f = fdGetFp(fd);
72     /*@=type@*/
73     int rc = 0;
74     int i;
75
76     if (f != NULL)
77     while (1) {
78         char line[BUFSIZ];
79
80         /* Read next line. */
81         s = fgets(line, sizeof(line) - 1, f);
82         if (s == NULL) {
83             /* XXX Ferror check needed */
84             break;
85         }
86
87         /* Skip comments. */
88         if ((se = strchr(s, '#')) != NULL) *se = '\0';
89
90         /* Trim white space. */
91         se = s + strlen(s);
92         while (se > s && (se[-1] == '\n' || se[-1] == '\r'))
93             *(--se) = '\0';
94         while (*s && strchr(" \f\n\r\t\v", *s) != NULL)
95             s++;
96         if (*s == '\0') continue;
97
98         /* Insure that file contains only ASCII */
99         if (*s < 32) {
100             rc = 1;
101             goto exit;
102         }
103
104         /* Concatenate next line in buffer. */
105         *se++ = ' ';
106         *se = '\0';
107         appendStringBuf(sb, s);
108     }
109
110     /*@-branchstate@*/
111     if (s == NULL)              /* XXX always true */
112         s = getStringBuf(sb);
113     /*@=branchstate@*/
114
115     if (!(s && *s)) {
116         rc = 1;
117         goto exit;
118     }
119
120     /* Glob manifest items. */
121     rc = rpmGlob(s, &ac, &av);
122     if (rc) goto exit;
123
124     /* Find 1st existing unprocessed arg. */
125     for (i = 0; i < argc; i++)
126         if (argv && argv[i]) break;
127
128     /* Concatenate existing unprocessed args after manifest contents. */
129     if (argv && i < argc) {
130         int nac = ac + (argc - i);
131         const char ** nav = xcalloc((nac + 1), sizeof(*nav));
132
133         if (ac)
134             memcpy(nav, av, ac * sizeof(*nav));
135         if ((argc - i) > 0)
136             memcpy(nav + ac, argv + i, (argc - i) * sizeof(*nav));
137         nav[nac] = NULL;
138
139         if (argvPtr)
140             *argvPtr = argv = _free(argv);
141         av = _free(av);
142         av = nav;
143         ac = nac;
144     }
145
146     /* Save new argc/argv list. */
147     if (argvPtr) {
148         *argvPtr = _free(*argvPtr);
149         *argvPtr = av;
150     }
151     if (argcPtr)
152         *argcPtr = ac;
153
154 exit:
155     /*@-branchstate@*/
156     if (argvPtr == NULL || (rc != 0 && av)) {
157         if (av)
158         for (i = 0; i < ac; i++)
159             /*@-unqualifiedtrans@*/av[i] = _free(av[i]); /*@=unqualifiedtrans@*/
160         /*@-dependenttrans@*/ av = _free(av); /*@=dependenttrans@*/
161     }
162     /*@=branchstate@*/
163     sb = freeStringBuf(sb);
164     /*@-nullstate@*/
165     return rc;
166     /*@=nullstate@*/
167 }