Bug Summary

File:rpmio/rpmlog.c
Warning:line 358, column 5
Value stored to 'ctx' is never read

Annotated Source Code

1/** \ingroup rpmio
2 * \file rpmio/rpmlog.c
3 */
4
5#include "system.h"
6#include <stdarg.h>
7#include <stdlib.h>
8#include <pthread.h>
9#include <errno(*__errno_location ()).h>
10#include <rpm/rpmlog.h>
11#include <rpm/rpmmacro.h>
12#include "debug.h"
13
14typedef struct rpmlogCtx_s * rpmlogCtx;
15struct rpmlogCtx_s {
16 pthread_rwlock_t lock;
17 unsigned mask;
18 int nrecs;
19 rpmlogRec recs;
20 rpmlogCallback cbfunc;
21 rpmlogCallbackData cbdata;
22 FILE *stdlog;
23};
24
25struct rpmlogRec_s {
26 int code; /* unused */
27 rpmlogLvl pri; /* priority */
28 char * message; /* log message string */
29};
30
31/* Force log context acquisition through a function */
32static rpmlogCtx rpmlogCtxAcquire(int write)
33{
34 static struct rpmlogCtx_s _globalCtx = { PTHREAD_RWLOCK_INITIALIZER{ { 0, 0, 0, 0, 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0 }, 0, 0 }
}
,
35 RPMLOG_UPTO(RPMLOG_NOTICE)((1 << (((unsigned)(RPMLOG_NOTICE))+1)) - 1),
36 0, NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0) };
37 rpmlogCtx ctx = &_globalCtx;
38 int xx;
39
40 /* XXX Silently failing is bad, but we can't very well use log here... */
41 if (write)
42 xx = pthread_rwlock_wrlock(&ctx->lock);
43 else
44 xx = pthread_rwlock_rdlock(&ctx->lock);
45
46 return (xx == 0) ? ctx : NULL((void*)0);
47}
48
49/* Release log context */
50static rpmlogCtx rpmlogCtxRelease(rpmlogCtx ctx)
51{
52 if (ctx)
53 pthread_rwlock_unlock(&ctx->lock);
54 return NULL((void*)0);
55}
56
57int rpmlogGetNrecs(void)
58{
59 rpmlogCtx ctx = rpmlogCtxAcquire(0);
60 int nrecs = -1;
61 if (ctx)
62 nrecs = ctx->nrecs;
63 rpmlogCtxRelease(ctx);
64 return nrecs;
65}
66
67int rpmlogCode(void)
68{
69 int code = -1;
70 rpmlogCtx ctx = rpmlogCtxAcquire(0);
71
72 if (ctx && ctx->recs != NULL((void*)0) && ctx->nrecs > 0)
73 code = ctx->recs[ctx->nrecs-1].code;
74
75 rpmlogCtxRelease(ctx);
76 return code;
77}
78
79const char * rpmlogMessage(void)
80{
81 const char *msg = _("(no error)")dcgettext ("rpm", "(no error)", 5);
82 rpmlogCtx ctx = rpmlogCtxAcquire(0);
83
84 if (ctx && ctx->recs != NULL((void*)0) && ctx->nrecs > 0)
85 msg = ctx->recs[ctx->nrecs-1].message;
86
87 rpmlogCtxRelease(ctx);
88 return msg;
89}
90
91const char * rpmlogRecMessage(rpmlogRec rec)
92{
93 return (rec != NULL((void*)0)) ? rec->message : NULL((void*)0);
94}
95
96rpmlogLvl rpmlogRecPriority(rpmlogRec rec)
97{
98 return (rec != NULL((void*)0)) ? rec->pri : (rpmlogLvl)-1;
99}
100
101void rpmlogPrint(FILE *f)
102{
103 rpmlogCtx ctx = rpmlogCtxAcquire(0);
104
105 if (ctx == NULL((void*)0))
106 return;
107
108 if (f == NULL((void*)0))
109 f = stderrstderr;
110
111 for (int i = 0; i < ctx->nrecs; i++) {
112 rpmlogRec rec = ctx->recs + i;
113 if (rec->message && *rec->message)
114 fprintf(f, " %s", rec->message);
115 }
116
117 rpmlogCtxRelease(ctx);
118}
119
120void rpmlogClose (void)
121{
122 rpmlogCtx ctx = rpmlogCtxAcquire(1);
123
124 if (ctx == NULL((void*)0))
125 return;
126
127 for (int i = 0; i < ctx->nrecs; i++) {
128 rpmlogRec rec = ctx->recs + i;
129 rec->message = _free(rec->message)rfree((rec->message));
130 }
131 ctx->recs = _free(ctx->recs)rfree((ctx->recs));
132 ctx->nrecs = 0;
133
134 rpmlogCtxRelease(ctx);
135}
136
137void rpmlogOpen (const char *ident, int option,
138 int facility)
139{
140}
141
142#ifdef NOTYET
143static unsigned rpmlogFacility = RPMLOG_USER;
144#endif
145
146int rpmlogSetMask (int mask)
147{
148 rpmlogCtx ctx = rpmlogCtxAcquire(mask ? 1 : 0);
149
150 int omask = -1;
151 if (ctx) {
152 omask = ctx->mask;
153 if (mask)
154 ctx->mask = mask;
155 }
156
157 rpmlogCtxRelease(ctx);
158 return omask;
159}
160
161rpmlogCallback rpmlogSetCallback(rpmlogCallback cb, rpmlogCallbackData data)
162{
163 rpmlogCtx ctx = rpmlogCtxAcquire(1);
164
165 rpmlogCallback ocb = NULL((void*)0);
166 if (ctx) {
167 ocb = ctx->cbfunc;
168 ctx->cbfunc = cb;
169 ctx->cbdata = data;
170 }
171
172 rpmlogCtxRelease(ctx);
173 return ocb;
174}
175
176FILE * rpmlogSetFile(FILE * fp)
177{
178 rpmlogCtx ctx = rpmlogCtxAcquire(1);
179
180 FILE * ofp = NULL((void*)0);
181 if (ctx) {
182 ofp = ctx->stdlog;
183 ctx->stdlog = fp;
184 }
185
186 rpmlogCtxRelease(ctx);
187 return ofp;
188}
189
190static const char * const rpmlogMsgPrefix[] = {
191 N_("fatal error: ")"fatal error: ",/*!< RPMLOG_EMERG */
192 N_("fatal error: ")"fatal error: ",/*!< RPMLOG_ALERT */
193 N_("fatal error: ")"fatal error: ",/*!< RPMLOG_CRIT */
194 N_("error: ")"error: ", /*!< RPMLOG_ERR */
195 N_("warning: ")"warning: ", /*!< RPMLOG_WARNING */
196 "", /*!< RPMLOG_NOTICE */
197 "", /*!< RPMLOG_INFO */
198 "D: ", /*!< RPMLOG_DEBUG */
199};
200
201#define ANSI_COLOR_BLACK"\x1b[30m" "\x1b[30m"
202#define ANSI_COLOR_RED"\x1b[31m" "\x1b[31m"
203#define ANSI_COLOR_GREEN"\x1b[32m" "\x1b[32m"
204#define ANSI_COLOR_YELLOW"\x1b[33m" "\x1b[33m"
205#define ANSI_COLOR_BLUE"\x1b[34m" "\x1b[34m"
206#define ANSI_COLOR_MAGENTA"\x1b[35m" "\x1b[35m"
207#define ANSI_COLOR_CYAN"\x1b[36m" "\x1b[36m"
208#define ANSI_COLOR_WHITE"\x1b[37m" "\x1b[37m"
209
210#define ANSI_BRIGHT_BLACK"\x1b[30;1m" "\x1b[30;1m"
211#define ANSI_BRIGHT_RED"\x1b[31;1m" "\x1b[31;1m"
212#define ANSI_BRIGHT_GREEN"\x1b[32;1m" "\x1b[32;1m"
213#define ANSI_BRIGHT_YELLOW"\x1b[33;1m" "\x1b[33;1m"
214#define ANSI_BRIGHT_BLUE"\x1b[34;1m" "\x1b[34;1m"
215#define ANSI_BRIGHT_MAGENTA"\x1b[35;1m" "\x1b[35;1m"
216#define ANSI_BRIGHT_CYAN"\x1b[36;1m" "\x1b[36;1m"
217#define ANSI_BRIGHT_WHITE"\x1b[37;1m" "\x1b[37;1m"
218
219#define ANSI_COLOR_BOLD"\x1b[1m" "\x1b[1m"
220#define ANSI_COLOR_RESET"\x1b[0m" "\x1b[0m"
221
222static const char *rpmlogMsgPrefixColor[] = {
223 ANSI_BRIGHT_RED"\x1b[31;1m", /*!< RPMLOG_EMERG */
224 ANSI_BRIGHT_RED"\x1b[31;1m", /*!< RPMLOG_ALERT */
225 ANSI_BRIGHT_RED"\x1b[31;1m", /*!< RPMLOG_CRIT */
226 ANSI_BRIGHT_RED"\x1b[31;1m", /*!< RPMLOG_ERR */
227 ANSI_BRIGHT_MAGENTA"\x1b[35;1m",/*!< RPMLOG_WARNING */
228 "", /*!< RPMLOG_NOTICE */
229 "", /*!< RPMLOG_INFO */
230 ANSI_BRIGHT_BLUE"\x1b[34;1m", /*!< RPMLOG_DEBUG */
231};
232
233const char * rpmlogLevelPrefix(rpmlogLvl pri)
234{
235 const char * prefix = "";
236 if (rpmlogMsgPrefix[pri] && *rpmlogMsgPrefix[pri])
237 prefix = _(rpmlogMsgPrefix[pri])dcgettext ("rpm", rpmlogMsgPrefix[pri], 5);
238 return prefix;
239}
240
241static const char * rpmlogLevelColor(rpmlogLvl pri)
242{
243 return rpmlogMsgPrefixColor[pri&0x7];
244}
245
246static int rpmlogDefault(FILE *stdlog, rpmlogRec rec)
247{
248 static const char fubar[] =
249 "Error occurred during writing of a log message";
250 FILE *msgout = (stdlog ? stdlog : stderrstderr);
251 char * color = rpmExpand("%{?_color_output}%{!?_color_output:auto}", NULL((void*)0));
252 const char * colorOn = NULL((void*)0);
253
254 if (!strcmp(color, "always") ||
255 (!strcmp(color, "auto") && isatty(fileno(msgout))))
256 colorOn = rpmlogLevelColor(rec->pri);
257
258 switch (rec->pri) {
259 case RPMLOG_INFO:
260 case RPMLOG_NOTICE:
261 msgout = (stdlog ? stdlog : stdoutstdout);
262 break;
263 case RPMLOG_EMERG:
264 case RPMLOG_ALERT:
265 case RPMLOG_CRIT:
266 case RPMLOG_ERR:
267 case RPMLOG_WARNING:
268 case RPMLOG_DEBUG:
269 if (colorOn && *colorOn)
270 if (fputs(rpmlogLevelColor(rec->pri), msgout) == EOF(-1)
271 && errno(*__errno_location ()) != EPIPE32)
272 perror(fubar);
273 break;
274 default:
275 break;
276 }
277
278 if (fputs(rpmlogLevelPrefix(rec->pri), msgout) == EOF(-1) && errno(*__errno_location ()) != EPIPE32)
279 perror(fubar);
280
281 switch (rec->pri) {
282 case RPMLOG_INFO:
283 case RPMLOG_NOTICE:
284 break;
285 case RPMLOG_EMERG:
286 case RPMLOG_ALERT:
287 case RPMLOG_CRIT:
288 case RPMLOG_ERR:
289 case RPMLOG_WARNING:
290 if (colorOn && *colorOn) {
291 if (fputs(ANSI_COLOR_RESET"\x1b[0m", msgout) == EOF(-1) && errno(*__errno_location ()) != EPIPE32)
292 perror(fubar);
293 if (fputs(ANSI_COLOR_BOLD"\x1b[1m", msgout) == EOF(-1) && errno(*__errno_location ()) != EPIPE32)
294 perror(fubar);
295 }
296 case RPMLOG_DEBUG:
297 default:
298 break;
299 }
300
301 if (rec->message)
302 (void) fputs(rec->message, msgout);
303
304 switch (rec->pri) {
305 case RPMLOG_INFO:
306 case RPMLOG_NOTICE:
307 break;
308 case RPMLOG_EMERG:
309 case RPMLOG_ALERT:
310 case RPMLOG_CRIT:
311 case RPMLOG_ERR:
312 case RPMLOG_WARNING:
313 case RPMLOG_DEBUG:
314 if (colorOn && *colorOn)
315 if (fputs(ANSI_COLOR_RESET"\x1b[0m", msgout) == EPIPE32 && errno(*__errno_location ()) != EPIPE32)
316 perror(fubar);
317 break;
318 default:
319 break;
320 }
321
322 (void) fflush(msgout);
323
324 return (rec->pri <= RPMLOG_CRIT ? RPMLOG_EXIT0x02 : 0);
325}
326
327/* FIX: rpmlogMsgPrefix[] dependent, not unqualified */
328/* FIX: rpmlogMsgPrefix[] may be NULL */
329static void dolog(struct rpmlogRec_s *rec, int saverec)
330{
331 static pthread_mutex_t serialize = PTHREAD_MUTEX_INITIALIZER{ { 0, 0, 0, 0, 0, 0, 0, { 0, 0 } } };
332
333 int cbrc = RPMLOG_DEFAULT0x01;
334 int needexit = 0;
335 FILE *clog = NULL((void*)0);
336 rpmlogCallbackData *cbdata = NULL((void*)0);
337 rpmlogCallback cbfunc = NULL((void*)0);
338 rpmlogCtx ctx = rpmlogCtxAcquire(saverec);
339
340 if (ctx == NULL((void*)0))
341 return;
342
343 /* Save copy of all messages at warning (or below == "more important"). */
344 if (saverec) {
345 ctx->recs = xrealloc(ctx->recs, (ctx->nrecs+2) * sizeof(*ctx->recs))rrealloc((ctx->recs), ((ctx->nrecs+2) * sizeof(*ctx->
recs)))
;
346 ctx->recs[ctx->nrecs].code = rec->code;
347 ctx->recs[ctx->nrecs].pri = rec->pri;
348 ctx->recs[ctx->nrecs].message = xstrdup(rec->message)rstrdup((rec->message));
349 ctx->recs[ctx->nrecs+1].code = 0;
350 ctx->recs[ctx->nrecs+1].message = NULL((void*)0);
351 ctx->nrecs++;
352 }
353 cbfunc = ctx->cbfunc;
354 cbdata = ctx->cbdata;
355 clog = ctx->stdlog;
356
357 /* Free the context for callback and actual log output */
358 ctx = rpmlogCtxRelease(ctx);
Value stored to 'ctx' is never read
359
360 /* Always serialize callback and output to avoid interleaved messages. */
361 if (pthread_mutex_lock(&serialize) == 0) {
362 if (cbfunc) {
363 cbrc = cbfunc(rec, cbdata);
364 needexit += cbrc & RPMLOG_EXIT0x02;
365 }
366
367 if (cbrc & RPMLOG_DEFAULT0x01) {
368 cbrc = rpmlogDefault(clog, rec);
369 needexit += cbrc & RPMLOG_EXIT0x02;
370 }
371 pthread_mutex_unlock(&serialize);
372 }
373
374 if (needexit)
375 exit(EXIT_FAILURE1);
376
377}
378
379void rpmlog (int code, const char *fmt, ...)
380{
381 unsigned pri = RPMLOG_PRI(code)((code) & 0x07);
382 unsigned mask = RPMLOG_MASK(pri)(1 << ((unsigned)(pri)));
383 int saverec = (pri <= RPMLOG_WARNING);
384 va_list ap;
385 int n;
386
387 if ((mask & rpmlogSetMask(0)) == 0)
388 return;
389
390 va_start(ap, fmt)__builtin_va_start(ap, fmt);
391 n = vsnprintf(NULL((void*)0), 0, fmt, ap);
392 va_end(ap)__builtin_va_end(ap);
393
394 if (n >= -1) {
395 struct rpmlogRec_s rec;
396 size_t nb = n + 1;
397 char *msg = xmalloc(nb)rmalloc((nb));
398
399 va_start(ap, fmt)__builtin_va_start(ap, fmt);
400 n = vsnprintf(msg, nb, fmt, ap);
401 va_end(ap)__builtin_va_end(ap);
402
403 rec.code = code;
404 rec.pri = pri;
405 rec.message = msg;
406
407 dolog(&rec, saverec);
408
409 free(msg);
410 }
411}