12 # define va_copy(DEST,SRC) __va_copy((DEST),(SRC))
14 # ifdef HAVE_VA_LIST_AS_ARRAY
15 # define va_copy(DEST,SRC) (*(DEST) = *(SRC))
17 # define va_copy(DEST,SRC) ((DEST) = (SRC))
24 static rpmlogRec recs = NULL;
27 * Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
28 * @param p memory to free
34 if (p != NULL) free((void *)p);
38 int rpmlogGetNrecs(void)
45 if (recs != NULL && nrecs > 0)
46 return recs[nrecs-1].code;
51 const char * rpmlogMessage(void)
53 if (recs != NULL && nrecs > 0)
54 return recs[nrecs-1].message;
55 return _("(no error)");
58 void rpmlogPrint(FILE *f)
66 for (i = 0; i < nrecs; i++) {
67 rpmlogRec rec = recs + i;
68 if (rec->message && *rec->message)
69 fprintf(f, " %s", rec->message);
73 void rpmlogClose (void)
78 for (i = 0; i < nrecs; i++) {
79 rpmlogRec rec = recs + i;
80 rec->message = _free(rec->message);
86 void rpmlogOpen (const char *ident, int option,
91 static unsigned rpmlogMask = RPMLOG_UPTO( RPMLOG_NOTICE );
94 static unsigned rpmlogFacility = RPMLOG_USER;
97 int rpmlogSetMask (int mask)
99 int omask = rpmlogMask;
105 static rpmlogCallback _rpmlogCallback = NULL;
107 rpmlogCallback rpmlogSetCallback(rpmlogCallback cb)
109 rpmlogCallback ocb = _rpmlogCallback;
110 _rpmlogCallback = cb;
114 static FILE * _stdlog = NULL;
116 FILE * rpmlogSetFile(FILE * fp)
118 FILE * ofp = _stdlog;
123 /*@-readonlytrans@*/ /* FIX: double indirection. */
124 static char *rpmlogMsgPrefix[] = {
125 N_("fatal error: "),/*!< RPMLOG_EMERG */
126 N_("fatal error: "),/*!< RPMLOG_ALERT */
127 N_("fatal error: "),/*!< RPMLOG_CRIT */
128 N_("error: "), /*!< RPMLOG_ERR */
129 N_("warning: "), /*!< RPMLOG_WARNING */
130 "", /*!< RPMLOG_NOTICE */
131 "", /*!< RPMLOG_INFO */
132 "D: ", /*!< RPMLOG_DEBUG */
135 #if !defined(HAVE_VSNPRINTF)
136 static inline int vsnprintf(char * buf, int nb,
137 const char * fmt, va_list ap)
139 return vsprintf(buf, fmt, ap);
143 /* FIX: rpmlogMsgPrefix[] dependent, not unqualified */
144 /* FIX: rpmlogMsgPrefix[] may be NULL */
145 static void vrpmlog (unsigned code, const char *fmt, va_list ap)
147 unsigned pri = RPMLOG_PRI(code);
148 unsigned mask = RPMLOG_MASK(pri);
150 unsigned fac = RPMLOG_FAC(code);
153 int msgnb = BUFSIZ, nb;
154 FILE * msgout = (_stdlog ? _stdlog : stderr);
156 if ((mask & rpmlogMask) == 0)
159 msgbuf = xmalloc(msgnb);
162 /* Allocate a sufficently large buffer for output. */
166 nb = vsnprintf(msgbuf, msgnb, fmt, apc);
167 if (nb > -1 && nb < msgnb)
169 if (nb > -1) /* glibc 2.1 (and later) */
173 msgbuf = xrealloc(msgbuf, msgnb);
176 msgbuf[msgnb - 1] = '\0';
179 /* Save copy of all messages at warning (or below == "more important"). */
180 if (pri <= RPMLOG_WARNING) {
183 recs = xmalloc((nrecs+2) * sizeof(*recs));
185 recs = xrealloc(recs, (nrecs+2) * sizeof(*recs));
186 recs[nrecs].code = code;
187 recs[nrecs].message = msg = xrealloc(msgbuf, strlen(msgbuf)+1);
188 msgbuf = NULL; /* XXX don't free at exit. */
189 recs[nrecs+1].code = 0;
190 recs[nrecs+1].message = NULL;
193 if (_rpmlogCallback) {
194 /* FIX: useless callback */
196 return; /* XXX Preserve legacy rpmError behavior. */
200 /* rpmMessage behavior */
205 msgout = (_stdlog ? _stdlog : stdout);
211 case RPMLOG_ERR: /* XXX Legacy rpmError behavior used stdout w/o prefix. */
217 if (rpmlogMsgPrefix[pri] && *rpmlogMsgPrefix[pri])
218 (void) fputs(_(rpmlogMsgPrefix[pri]), msgout);
220 (void) fputs(msg, msgout);
221 (void) fflush(msgout);
222 msgbuf = _free(msgbuf);
223 if (pri <= RPMLOG_CRIT)
227 void rpmlog (int code, const char *fmt, ...)
233 vrpmlog(code, fmt, ap);
237 int rpmErrorCode(void)
242 const char * rpmErrorString(void)
244 return rpmlogMessage();
247 rpmlogCallback rpmErrorSetCallback(rpmlogCallback cb)
249 return rpmlogSetCallback(cb);