Bug Summary

File:lib/rpmgi.c
Warning:line 158, column 2
Value stored to 'fn' is never read

Annotated Source Code

1/** \ingroup rpmio
2 * \file lib/rpmgi.c
3 */
4#include "system.h"
5
6#include <errno(*__errno_location ()).h>
7
8#include <rpm/rpmtypes.h>
9#include <rpm/rpmlib.h> /* rpmReadPackageFile */
10#include <rpm/rpmts.h>
11#include <rpm/rpmmacro.h> /* XXX rpmExpand */
12#include <rpm/rpmfileutil.h>
13#include <rpm/rpmlog.h>
14
15#include "lib/rpmgi.h"
16#include "lib/manifest.h"
17
18#include "debug.h"
19
20#define MANIFEST_RECURSIONS1000 1000 /* Max. number of allowed manifest recursions */
21
22RPM_GNUC_INTERNAL__attribute__((visibility("hidden")))
23rpmgiFlags giFlags = RPMGI_NONE;
24
25/** \ingroup rpmgi
26 */
27struct rpmgi_s {
28 rpmts ts; /*!< Iterator transaction set. */
29
30 rpmgiFlags flags; /*!< Iterator control bits. */
31 int i; /*!< Element index. */
32 int errors;
33
34 ARGV_t argv;
35 int argc;
36
37 int curLvl; /*!< Current recursion level */
38 int recLvls[MANIFEST_RECURSIONS1000]; /*!< Reversed end index for given level */
39
40};
41
42/**
43 * Open a file after macro expanding path.
44 * @todo There are two error messages printed on header, then manifest failures.
45 * @param path file path
46 * @param fmode open mode
47 * @return file handle
48 */
49static FD_t rpmgiOpen(const char * path, const char * fmode)
50{
51 char * fn = rpmExpand(path, NULL((void*)0));
52 FD_t fd = Fopen(fn, fmode);
53
54 if (fd == NULL((void*)0) || Ferror(fd)) {
55 rpmlog(RPMLOG_ERR, _("open of %s failed: %s\n")dcgettext ("rpm", "open of %s failed: %s\n", 5), fn, Fstrerror(fd));
56 if (fd != NULL((void*)0)) (void) Fclose(fd);
57 fd = NULL((void*)0);
58 }
59 free(fn);
60
61 return fd;
62}
63
64/**
65 * Load manifest into iterator arg list.
66 * @param gi generalized iterator
67 * @param path file path
68 * @return RPMRC_OK on success
69 */
70static rpmRC rpmgiLoadManifest(rpmgi gi, const char * path)
71{
72 FD_t fd = rpmgiOpen(path, "r.ufdio");
73 rpmRC rpmrc = RPMRC_FAIL;
74
75 if (fd != NULL((void*)0)) {
76 rpmrc = rpmReadPackageManifest(fd, &gi->argc, &gi->argv);
77 (void) Fclose(fd);
78 }
79 return rpmrc;
80}
81
82/**
83 * Return header from package.
84 * @param gi generalized iterator
85 * @param path file path
86 * @retval hdrp header (NULL on failure)
87 * @return 1 if path could be opened, 0 if not
88 */
89static int rpmgiReadHeader(rpmgi gi, const char * path, Header * hdrp)
90{
91 FD_t fd = rpmgiOpen(path, "r.ufdio");
92 Header h = NULL((void*)0);
93
94 if (fd != NULL((void*)0)) {
95 /* XXX what if path needs expansion? */
96 rpmRC rpmrc = rpmReadPackageFile(gi->ts, fd, path, &h);
97
98 (void) Fclose(fd);
99
100 switch (rpmrc) {
101 case RPMRC_NOTFOUND:
102 /* XXX Read a package manifest. Restart ftswalk on success. */
103 case RPMRC_FAIL:
104 default:
105 h = headerFree(h);
106 break;
107 case RPMRC_NOTTRUSTED:
108 case RPMRC_NOKEY:
109 case RPMRC_OK:
110 break;
111 }
112 }
113
114 *hdrp = h;
115 return (fd != NULL((void*)0));
116}
117
118/**
119 * Read next header from package, lazily expanding manifests as found.
120 * @todo An empty file read as manifest truncates argv returning RPMRC_NOTFOUND.
121 * @todo Chained manifests lose an arg someplace.
122 * @param gi generalized iterator
123 * @return header on success
124 */
125static Header rpmgiLoadReadHeader(rpmgi gi)
126{
127 Header h = NULL((void*)0);
128
129 if (gi->argv != NULL((void*)0) && gi->argv[gi->i] != NULL((void*)0))
130 do {
131 char * fn = gi->argv[gi->i];
132 int rc;
133
134 while (gi->recLvls[gi->curLvl] > gi->argc - gi->i)
135 gi->curLvl--;
136
137 rc = rpmgiReadHeader(gi, fn, &h);
138
139 if (h != NULL((void*)0) || (gi->flags & RPMGI_NOMANIFEST) || rc == 0)
140 break;
141
142 if (gi->curLvl == MANIFEST_RECURSIONS1000 - 1) {
143 rpmlog(RPMLOG_ERR,
144 _("Max level of manifest recursion exceeded: %s\n")dcgettext ("rpm", "Max level of manifest recursion exceeded: %s\n"
, 5)
, fn);
145 break;
146 }
147 gi->curLvl++;
148 gi->recLvls[gi->curLvl] = gi->argc - gi->i;
149
150 /* Not a header, so try for a manifest. */
151 gi->argv[gi->i] = NULL((void*)0); /* Mark the insertion point */
152 if (rpmgiLoadManifest(gi, fn) != RPMRC_OK) {
153 gi->argv[gi->i] = fn; /* Manifest failed, restore fn */
154 rpmlog(RPMLOG_ERR,
155 _("%s: not an rpm package (or package manifest)\n")dcgettext ("rpm", "%s: not an rpm package (or package manifest)\n"
, 5)
, fn);
156 break;
157 }
158 fn = _free(fn)rfree((fn));
Value stored to 'fn' is never read
159 } while (1);
160
161 return h;
162}
163
164
165/**
166 * Append globbed arg list to iterator.
167 * @param gi generalized iterator
168 * @param argv arg list to be globbed (or NULL)
169 */
170static void rpmgiGlobArgv(rpmgi gi, ARGV_const_t argv)
171{
172 if (argv == NULL((void*)0)) return;
173
174 /* XXX Expand globs only if requested */
175 if ((gi->flags & RPMGI_NOGLOB)) {
176 argvAppend(&gi->argv, argv);
177 } else {
178 const char * arg;
179 while ((arg = *argv++) != NULL((void*)0)) {
180 char * t = rpmEscapeSpaces(arg);
181 char ** av = NULL((void*)0);
182
183 if (rpmGlob(t, NULL((void*)0), &av) == 0) {
184 argvAppend(&gi->argv, av);
185 argvFree(av);
186 }
187 free(t);
188 }
189 }
190 gi->argc = argvCount(gi->argv);
191
192 return;
193}
194
195rpmgi rpmgiFree(rpmgi gi)
196{
197 if (gi != NULL((void*)0)) {
198 rpmtsFree(gi->ts);
199 argvFree(gi->argv);
200
201 memset(gi, 0, sizeof(*gi)); /* XXX trash and burn */
202 free(gi);
203 }
204 return NULL((void*)0);
205}
206
207rpmgi rpmgiNew(rpmts ts, rpmgiFlags flags, ARGV_const_t argv)
208{
209 rpmgi gi = xcalloc(1, sizeof(*gi))rcalloc((1), (sizeof(*gi)));
210
211 gi->ts = rpmtsLink(ts);
212
213 gi->flags = flags;
214 gi->i = -1;
215 gi->errors = 0;
216
217 gi->argv = argvNew();
218 gi->argc = 0;
219 rpmgiGlobArgv(gi, argv);
220
221 gi->curLvl = 0;
222 gi->recLvls[gi->curLvl] = 1;
223
224 return gi;
225}
226
227Header rpmgiNext(rpmgi gi)
228{
229 Header h = NULL((void*)0);
230
231 if (gi != NULL((void*)0) && ++gi->i >= 0) {
232 /*
233 * Read next header, lazily expanding manifests as found,
234 * count + skip errors.
235 */
236 while (gi->i < gi->argc) {
237 if ((h = rpmgiLoadReadHeader(gi)) != NULL((void*)0))
238 break;
239 gi->errors++;
240 gi->i++;
241 }
242
243 /* Out of things to try, end of iteration */
244 if (h == NULL((void*)0))
245 gi->i = -1;
246 }
247
248 return h;
249}
250
251int rpmgiNumErrors(rpmgi gi)
252{
253 return (gi != NULL((void*)0) ? gi->errors : -1);
254}