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;
26 int rpmlogGetNrecs(void)
33 if (recs != NULL && nrecs > 0)
34 return recs[nrecs-1].code;
39 const char * rpmlogMessage(void)
41 if (recs != NULL && nrecs > 0)
42 return recs[nrecs-1].message;
43 return _("(no error)");
46 void rpmlogPrint(FILE *f)
54 for (i = 0; i < nrecs; i++) {
55 rpmlogRec rec = recs + i;
56 if (rec->message && *rec->message)
57 fprintf(f, " %s", rec->message);
61 void rpmlogClose (void)
66 for (i = 0; i < nrecs; i++) {
67 rpmlogRec rec = recs + i;
68 rec->message = _free(rec->message);
74 void rpmlogOpen (const char *ident, int option,
79 static unsigned rpmlogMask = RPMLOG_UPTO( RPMLOG_NOTICE );
82 static unsigned rpmlogFacility = RPMLOG_USER;
85 int rpmlogSetMask (int mask)
87 int omask = rpmlogMask;
93 static rpmlogCallback _rpmlogCallback = NULL;
95 rpmlogCallback rpmlogSetCallback(rpmlogCallback cb)
97 rpmlogCallback ocb = _rpmlogCallback;
102 static FILE * _stdlog = NULL;
104 FILE * rpmlogSetFile(FILE * fp)
106 FILE * ofp = _stdlog;
111 static char *rpmlogMsgPrefix[] = {
112 N_("fatal error: "),/*!< RPMLOG_EMERG */
113 N_("fatal error: "),/*!< RPMLOG_ALERT */
114 N_("fatal error: "),/*!< RPMLOG_CRIT */
115 N_("error: "), /*!< RPMLOG_ERR */
116 N_("warning: "), /*!< RPMLOG_WARNING */
117 "", /*!< RPMLOG_NOTICE */
118 "", /*!< RPMLOG_INFO */
119 "D: ", /*!< RPMLOG_DEBUG */
122 #if !defined(HAVE_VSNPRINTF)
123 static inline int vsnprintf(char * buf, int nb,
124 const char * fmt, va_list ap)
126 return vsprintf(buf, fmt, ap);
130 /* FIX: rpmlogMsgPrefix[] dependent, not unqualified */
131 /* FIX: rpmlogMsgPrefix[] may be NULL */
132 static void vrpmlog (unsigned code, const char *fmt, va_list ap)
134 unsigned pri = RPMLOG_PRI(code);
135 unsigned mask = RPMLOG_MASK(pri);
137 unsigned fac = RPMLOG_FAC(code);
140 int msgnb = BUFSIZ, nb;
141 FILE * msgout = (_stdlog ? _stdlog : stderr);
143 if ((mask & rpmlogMask) == 0)
146 msgbuf = xmalloc(msgnb);
149 /* Allocate a sufficently large buffer for output. */
153 nb = vsnprintf(msgbuf, msgnb, fmt, apc);
154 if (nb > -1 && nb < msgnb)
156 if (nb > -1) /* glibc 2.1 (and later) */
160 msgbuf = xrealloc(msgbuf, msgnb);
163 msgbuf[msgnb - 1] = '\0';
166 /* Save copy of all messages at warning (or below == "more important"). */
167 if (pri <= RPMLOG_WARNING) {
170 recs = xmalloc((nrecs+2) * sizeof(*recs));
172 recs = xrealloc(recs, (nrecs+2) * sizeof(*recs));
173 recs[nrecs].code = code;
174 recs[nrecs].message = msg = xrealloc(msgbuf, strlen(msgbuf)+1);
175 msgbuf = NULL; /* XXX don't free at exit. */
176 recs[nrecs+1].code = 0;
177 recs[nrecs+1].message = NULL;
180 if (_rpmlogCallback) {
181 /* FIX: useless callback */
183 return; /* XXX Preserve legacy rpmError behavior. */
187 /* rpmMessage behavior */
192 msgout = (_stdlog ? _stdlog : stdout);
198 case RPMLOG_ERR: /* XXX Legacy rpmError behavior used stdout w/o prefix. */
204 if (rpmlogMsgPrefix[pri] && *rpmlogMsgPrefix[pri])
205 (void) fputs(_(rpmlogMsgPrefix[pri]), msgout);
207 (void) fputs(msg, msgout);
208 (void) fflush(msgout);
209 msgbuf = _free(msgbuf);
210 if (pri <= RPMLOG_CRIT)
214 void rpmlog (int code, const char *fmt, ...)
220 vrpmlog(code, fmt, ap);
224 int rpmErrorCode(void)
229 const char * rpmErrorString(void)
231 return rpmlogMessage();
234 rpmlogCallback rpmErrorSetCallback(rpmlogCallback cb)
236 return rpmlogSetCallback(cb);