1 /** \ingroup rpmcli
2 * \file lib/manifest.c
3 */
4
5 #include "system.h"
6
7 #include <rpm/rpmlog.h>
8 #include <rpm/rpmfileutil.h>
9 #include <rpm/argv.h>
10
11 #include "lib/manifest.h"
12
13 #include "debug.h"
14
15
rpmPermsString(int mode)16 char * rpmPermsString(int mode)
17 {
18 char *perms = xstrdup("----------");
19
20 if (S_ISREG(mode))
21 perms[0] = '-';
22 else if (S_ISDIR(mode))
23 perms[0] = 'd';
24 else if (S_ISLNK(mode))
25 perms[0] = 'l';
26 else if (S_ISFIFO(mode))
27 perms[0] = 'p';
28 else if (S_ISSOCK(mode))
29 perms[0] = 's';
30 else if (S_ISCHR(mode))
31 perms[0] = 'c';
32 else if (S_ISBLK(mode))
33 perms[0] = 'b';
34 else
35 perms[0] = '?';
36
37 if (mode & S_IRUSR) perms[1] = 'r';
38 if (mode & S_IWUSR) perms[2] = 'w';
39 if (mode & S_IXUSR) perms[3] = 'x';
40
41 if (mode & S_IRGRP) perms[4] = 'r';
42 if (mode & S_IWGRP) perms[5] = 'w';
43 if (mode & S_IXGRP) perms[6] = 'x';
44
45 if (mode & S_IROTH) perms[7] = 'r';
46 if (mode & S_IWOTH) perms[8] = 'w';
47 if (mode & S_IXOTH) perms[9] = 'x';
48
49 if (mode & S_ISUID)
50 perms[3] = ((mode & S_IXUSR) ? 's' : 'S');
51
52 if (mode & S_ISGID)
53 perms[6] = ((mode & S_IXGRP) ? 's' : 'S');
54
55 if (mode & S_ISVTX)
56 perms[9] = ((mode & S_IXOTH) ? 't' : 'T');
57
58 return perms;
59 }
60
61 /**@todo Infinite loops through manifest files exist, operator error for now. */
rpmReadPackageManifest(FD_t fd,int * argcPtr,char *** argvPtr)62 rpmRC rpmReadPackageManifest(FD_t fd, int * argcPtr, char *** argvPtr)
63 {
64 ARGV_t sb = NULL;
65 char * s = NULL;
66 char * se;
67 int ac = 0;
68 char ** av = NULL;
69 int argc = (argcPtr ? *argcPtr : 0);
70 char ** argv = (argvPtr ? *argvPtr : NULL);
71 FILE * f = fdopen(Fileno(fd), "r");
72 rpmRC rpmrc = RPMRC_OK;
73 int i, j, next, npre;
74
75 if (f != NULL)
76 while (1) {
77 char line[BUFSIZ];
78
79 /* Read next line. */
80 s = fgets(line, sizeof(line) - 1, f);
81 if (s == NULL) {
82 /* XXX Ferror check needed */
83 break;
84 }
85
86 /* Skip comments. */
87 if (*s == '#')
88 continue;
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 /* Sanity checks: skip obviously binary lines */
99 if (*s < 32) {
100 s = NULL;
101 rpmrc = RPMRC_NOTFOUND;
102 goto exit;
103 }
104
105 /* Concatenate next line in buffer. */
106 *se = '\0';
107 argvAdd(&sb, s);
108 }
109
110 s = argvJoin(sb, " ");
111
112 if (!(s && *s)) {
113 rpmrc = RPMRC_NOTFOUND;
114 goto exit;
115 }
116
117 /* Glob manifest items. */
118 rpmrc = (rpmGlob(s, &ac, &av) == 0 ? RPMRC_OK : RPMRC_FAIL);
119 if (rpmrc != RPMRC_OK) goto exit;
120
121 /* Sanity check: skip dash (for stdin) */
122 for (i = 0; i < ac; i++) {
123 if (rstreq(av[i], "-")) {
124 rpmrc = RPMRC_NOTFOUND;
125 goto exit;
126 }
127 }
128
129 rpmlog(RPMLOG_DEBUG, "adding %d args from manifest.\n", ac);
130
131 /* Count non-NULL args, keeping track of 1st arg after last NULL. */
132 npre = 0;
133 next = 0;
134 if (argv != NULL)
135 for (i = 0; i < argc; i++) {
136 if (argv[i] != NULL)
137 npre++;
138 else if (i >= next)
139 next = i + 1;
140 }
141
142 /* Copy old arg list, inserting manifest before argv[next]. */
143 if (argv != NULL) {
144 int nac = npre + ac;
145 char ** nav = xcalloc((nac + 1), sizeof(*nav));
146
147 for (i = 0, j = 0; i < next; i++) {
148 if (argv[i] != NULL)
149 nav[j++] = argv[i];
150 }
151
152 if (ac)
153 memcpy(nav + j, av, ac * sizeof(*nav));
154 if ((argc - next) > 0)
155 memcpy(nav + j + ac, argv + next, (argc - next) * sizeof(*nav));
156 nav[nac] = NULL;
157
158 if (argvPtr)
159 *argvPtr = argv = _free(argv);
160 av = _free(av);
161 av = nav;
162 ac = nac;
163 }
164
165 /* Save new argc/argv list. */
166 if (argvPtr) {
167 *argvPtr = _free(*argvPtr);
168 *argvPtr = av;
169 }
170 if (argcPtr)
171 *argcPtr = ac;
172
173 exit:
174 if (f)
175 fclose(f);
176 if (argvPtr == NULL || (rpmrc != RPMRC_OK && av)) {
177 if (av)
178 for (i = 0; i < ac; i++)
179 av[i] = _free(av[i]);
180 av = _free(av);
181 }
182 argvFree(sb);
183 free(s);
184 /* FIX: *argvPtr may be NULL. */
185 return rpmrc;
186 }
187