#include "system.h"
#include <stdarg.h>
-#include "rpmlog.h"
+#include <stdlib.h>
+#include <rpm/rpmlog.h>
#include "debug.h"
-/*@access rpmlogRec @*/
-
static int nrecs = 0;
-static /*@only@*/ /*@null@*/ rpmlogRec recs = NULL;
+static rpmlogRec recs = NULL;
+
+struct rpmlogRec_s {
+ int code; /* unused */
+ rpmlogLvl pri; /* priority */
+ char * message; /* log message string */
+};
int rpmlogGetNrecs(void)
{
int rpmlogCode(void)
{
- if (nrecs > 0)
+ if (recs != NULL && nrecs > 0)
return recs[nrecs-1].code;
return -1;
}
const char * rpmlogMessage(void)
{
- if (nrecs > 0)
+ if (recs != NULL && nrecs > 0)
return recs[nrecs-1].message;
return _("(no error)");
}
+const char * rpmlogRecMessage(rpmlogRec rec)
+{
+ assert(rec != NULL);
+ return (rec->message);
+}
+
+rpmlogLvl rpmlogRecPriority(rpmlogRec rec)
+{
+ assert(rec != NULL);
+ return (rec->pri);
+}
+
void rpmlogPrint(FILE *f)
{
int i;
if (f == NULL)
f = stderr;
+ if (recs)
for (i = 0; i < nrecs; i++) {
rpmlogRec rec = recs + i;
if (rec->message && *rec->message)
{
int i;
+ if (recs)
for (i = 0; i < nrecs; i++) {
rpmlogRec rec = recs + i;
- if (rec->message) {
- free((void *)rec->message);
- rec->message = NULL;
- }
+ rec->message = _free(rec->message);
}
- free(recs);
- recs = NULL;
+ recs = _free(recs);
nrecs = 0;
}
-void rpmlogOpen (/*@unused@*/ const char *ident, /*@unused@*/ int option,
- /*@unused@*/ int facility)
+void rpmlogOpen (const char *ident, int option,
+ int facility)
{
}
-static int rpmlogMask = RPMLOG_UPTO( RPMLOG_NOTICE );
-static /*@unused@*/ int rpmlogFacility = RPMLOG_USER;
+static unsigned rpmlogMask = RPMLOG_UPTO( RPMLOG_NOTICE );
+
+#ifdef NOTYET
+static unsigned rpmlogFacility = RPMLOG_USER;
+#endif
int rpmlogSetMask (int mask)
{
return omask;
}
-static /*@null@*/ rpmlogCallback _rpmlogCallback = NULL;
+static rpmlogCallback _rpmlogCallback = NULL;
+static rpmlogCallbackData _rpmlogCallbackData = NULL;
-rpmlogCallback rpmlogSetCallback(rpmlogCallback cb)
+rpmlogCallback rpmlogSetCallback(rpmlogCallback cb, rpmlogCallbackData data)
{
rpmlogCallback ocb = _rpmlogCallback;
_rpmlogCallback = cb;
+ _rpmlogCallbackData = data;
return ocb;
}
-static char *rpmlogMsgPrefix[] = {
+static FILE * _stdlog = NULL;
+
+static int rpmlogDefault(rpmlogRec rec)
+{
+ FILE *msgout = (_stdlog ? _stdlog : stderr);
+
+ switch (rec->pri) {
+ case RPMLOG_INFO:
+ case RPMLOG_NOTICE:
+ msgout = (_stdlog ? _stdlog : stdout);
+ break;
+ case RPMLOG_EMERG:
+ case RPMLOG_ALERT:
+ case RPMLOG_CRIT:
+ case RPMLOG_ERR:
+ case RPMLOG_WARNING:
+ case RPMLOG_DEBUG:
+ default:
+ break;
+ }
+
+ (void) fputs(rpmlogLevelPrefix(rec->pri), msgout);
+
+ (void) fputs(rec->message, msgout);
+ (void) fflush(msgout);
+
+ return (rec->pri <= RPMLOG_CRIT ? RPMLOG_EXIT : 0);
+}
+
+
+FILE * rpmlogSetFile(FILE * fp)
+{
+ FILE * ofp = _stdlog;
+ _stdlog = fp;
+ return ofp;
+}
+
+static const char * const rpmlogMsgPrefix[] = {
N_("fatal error: "),/*!< RPMLOG_EMERG */
N_("fatal error: "),/*!< RPMLOG_ALERT */
N_("fatal error: "),/*!< RPMLOG_CRIT */
"D: ", /*!< RPMLOG_DEBUG */
};
-#if !defined(HAVE_VSNPRINTF)
-static inline int vsnprintf(char * buf, /*@unused@*/ int nb,
- const char * fmt, va_list ap)
+const char * rpmlogLevelPrefix(rpmlogLvl pri)
{
- return vsprintf(buf, fmt, ap);
+ const char * prefix = "";
+ if (rpmlogMsgPrefix[pri] && *rpmlogMsgPrefix[pri])
+ prefix = _(rpmlogMsgPrefix[pri]);
+ return prefix;
}
-#endif
-static void vrpmlog (unsigned code, const char *fmt, va_list ap)
+/* FIX: rpmlogMsgPrefix[] dependent, not unqualified */
+/* FIX: rpmlogMsgPrefix[] may be NULL */
+static void dolog (struct rpmlogRec_s *rec)
{
- int pri = RPMLOG_PRI(code);
- int mask = RPMLOG_MASK(pri);
- /*@unused@*/ int fac = RPMLOG_FAC(code);
- char *msgbuf, *msg;
- int freeMsgbuf = 1;
- int msgnb = BUFSIZ, nb;
- FILE * msgout = stderr;
- rpmlogRec rec;
-
- if ((mask & rpmlogMask) == 0)
- return;
-
- msgbuf = xmalloc(msgnb);
- *msgbuf = '\0';
-
- /* Allocate a sufficently large buffer for output. */
- while (1) {
- va_list apc;
- /*@-sysunrecog@*/ __va_copy(apc, ap); /*@=sysunrecog@*/
- /*@-unrecog@*/ nb = vsnprintf(msgbuf, msgnb, fmt, apc); /*@=unrecog@*/
- if (nb > -1 && nb < msgnb)
- break;
- if (nb > -1) /* glibc 2.1 */
- msgnb = nb+1;
- else /* glibc 2.0 */
- msgnb *= 2;
- msgbuf = xrealloc(msgbuf, msgnb);
- }
- msgbuf[msgnb - 1] = '\0';
- msg = msgbuf;
+ int cbrc = RPMLOG_DEFAULT;
+ int needexit = 0;
/* Save copy of all messages at warning (or below == "more important"). */
- if (pri <= RPMLOG_WARNING) {
-
- if (recs == NULL)
- recs = xmalloc((nrecs+2) * sizeof(*recs));
- else
- recs = xrealloc(recs, (nrecs+2) * sizeof(*recs));
+ if (rec->pri <= RPMLOG_WARNING) {
+ recs = xrealloc(recs, (nrecs+2) * sizeof(*recs));
+ recs[nrecs].code = rec->code;
+ recs[nrecs].pri = rec->pri;
+ recs[nrecs].message = xstrdup(rec->message);
recs[nrecs+1].code = 0;
recs[nrecs+1].message = NULL;
- rec = recs + nrecs;
++nrecs;
-
- rec->code = code;
- rec->message = msgbuf;
- freeMsgbuf = 0;
-
- if (_rpmlogCallback) {
- _rpmlogCallback();
- return; /* XXX Preserve legacy rpmError behavior. */
- }
}
- /* rpmMessage behavior */
-
- switch (pri) {
- case RPMLOG_INFO:
- case RPMLOG_NOTICE:
- msgout = stdout;
- break;
-
- case RPMLOG_EMERG:
- case RPMLOG_ALERT:
- case RPMLOG_CRIT:
- case RPMLOG_ERR: /* XXX Legacy rpmError behavior used stdout w/o prefix. */
- case RPMLOG_WARNING:
- case RPMLOG_DEBUG:
- break;
+ if (_rpmlogCallback) {
+ cbrc = _rpmlogCallback(rec, _rpmlogCallbackData);
+ needexit += cbrc & RPMLOG_EXIT;
}
- if (rpmlogMsgPrefix[pri] && *rpmlogMsgPrefix[pri])
- fputs(_(rpmlogMsgPrefix[pri]), msgout);
-
- fputs(msg, msgout);
- fflush(msgout);
- if (freeMsgbuf)
- free(msgbuf);
- if (pri <= RPMLOG_CRIT)
+ if (cbrc & RPMLOG_DEFAULT) {
+ cbrc = rpmlogDefault(rec);
+ needexit += cbrc & RPMLOG_EXIT;
+ }
+
+ if (needexit)
exit(EXIT_FAILURE);
}
void rpmlog (int code, const char *fmt, ...)
{
+ unsigned pri = RPMLOG_PRI(code);
+ unsigned mask = RPMLOG_MASK(pri);
va_list ap;
+ int n;
+
+ if ((mask & rpmlogMask) == 0)
+ return;
va_start(ap, fmt);
- vrpmlog(code, fmt, ap);
+ n = vsnprintf(NULL, 0, fmt, ap);
va_end(ap);
-}
-int rpmErrorCode(void)
-{
- return rpmlogCode();
-}
+ if (n >= -1) {
+ struct rpmlogRec_s rec;
+ size_t nb = n + 1;
+ char *msg = xmalloc(nb);
-const char * rpmErrorString(void)
-{
- return rpmlogMessage();
-}
+ va_start(ap, fmt);
+ n = vsnprintf(msg, nb, fmt, ap);
+ va_end(ap);
-rpmlogCallback rpmErrorSetCallback(rpmlogCallback cb)
-{
- return rpmlogSetCallback(cb);
+ rec.code = code;
+ rec.pri = pri;
+ rec.message = msg;
+
+ dolog(&rec);
+
+ free(msg);
+ }
}
+