10 /*@access rpmlogRec @*/
13 static /*@only@*/ /*@null@*/ rpmlogRec recs = NULL;
16 * Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
17 * @param p memory to free
20 /*@unused@*/ static inline /*@null@*/ void *
21 _free(/*@only@*/ /*@null@*/ const void * p) /*@modifies p@*/
23 if (p != NULL) free((void *)p);
27 int rpmlogGetNrecs(void)
34 if (recs != NULL && nrecs > 0)
35 return recs[nrecs-1].code;
40 const char * rpmlogMessage(void)
42 if (recs != NULL && nrecs > 0)
43 return recs[nrecs-1].message;
44 return _("(no error)");
47 void rpmlogPrint(FILE *f)
55 for (i = 0; i < nrecs; i++) {
56 rpmlogRec rec = recs + i;
57 if (rec->message && *rec->message)
58 fprintf(f, " %s", rec->message);
62 void rpmlogClose (void)
67 for (i = 0; i < nrecs; i++) {
68 rpmlogRec rec = recs + i;
69 rec->message = _free(rec->message);
75 void rpmlogOpen (/*@unused@*/ const char *ident, /*@unused@*/ int option,
76 /*@unused@*/ int facility)
80 static int rpmlogMask = RPMLOG_UPTO( RPMLOG_NOTICE );
81 static /*@unused@*/ int rpmlogFacility = RPMLOG_USER;
83 int rpmlogSetMask (int mask)
85 int omask = rpmlogMask;
91 static /*@null@*/ rpmlogCallback _rpmlogCallback = NULL;
93 rpmlogCallback rpmlogSetCallback(rpmlogCallback cb)
95 rpmlogCallback ocb = _rpmlogCallback;
100 /*@-readonlytrans@*/ /* FIX: double indeirection. */
101 /*@observer@*/ static char *rpmlogMsgPrefix[] = {
102 N_("fatal error: "),/*!< RPMLOG_EMERG */
103 N_("fatal error: "),/*!< RPMLOG_ALERT */
104 N_("fatal error: "),/*!< RPMLOG_CRIT */
105 N_("error: "), /*!< RPMLOG_ERR */
106 N_("warning: "), /*!< RPMLOG_WARNING */
107 "", /*!< RPMLOG_NOTICE */
108 "", /*!< RPMLOG_INFO */
109 "D: ", /*!< RPMLOG_DEBUG */
113 #if !defined(HAVE_VSNPRINTF)
114 static inline int vsnprintf(char * buf, /*@unused@*/ int nb,
115 const char * fmt, va_list ap)
117 return vsprintf(buf, fmt, ap);
121 static void vrpmlog (unsigned code, const char *fmt, va_list ap)
122 /*@modifies internalState @*/
124 int pri = RPMLOG_PRI(code);
125 int mask = RPMLOG_MASK(pri);
126 /*@unused@*/ int fac = RPMLOG_FAC(code);
128 int msgnb = BUFSIZ, nb;
129 FILE * msgout = stderr;
131 if ((mask & rpmlogMask) == 0)
134 msgbuf = xmalloc(msgnb);
137 /* Allocate a sufficently large buffer for output. */
139 #if defined(__GLIBC__) && __GLIBC__ == 2 && __GLIBC_MINOR__ == 0
140 /*@-unrecog@*/ nb = vsnprintf(msgbuf, msgnb, fmt, ap); /*@=unrecog@*/
143 /*@-sysunrecog -usedef@*/ __va_copy(apc, ap); /*@=sysunrecog =usedef@*/
144 /*@-unrecog@*/ nb = vsnprintf(msgbuf, msgnb, fmt, apc); /*@=unrecog@*/
146 if (nb > -1 && nb < msgnb)
148 if (nb > -1) /* glibc 2.1 */
152 msgbuf = xrealloc(msgbuf, msgnb);
154 msgbuf[msgnb - 1] = '\0';
157 /* Save copy of all messages at warning (or below == "more important"). */
158 if (pri <= RPMLOG_WARNING) {
161 recs = xmalloc((nrecs+2) * sizeof(*recs));
163 recs = xrealloc(recs, (nrecs+2) * sizeof(*recs));
164 recs[nrecs].code = code;
165 recs[nrecs].message = msg = xrealloc(msgbuf, strlen(msgbuf)+1);
166 msgbuf = NULL; /* XXX don't free at exit. */
167 recs[nrecs+1].code = 0;
168 recs[nrecs+1].message = NULL;
171 if (_rpmlogCallback) {
173 return; /* XXX Preserve legacy rpmError behavior. */
177 /* rpmMessage behavior */
188 case RPMLOG_ERR: /* XXX Legacy rpmError behavior used stdout w/o prefix. */
194 if (rpmlogMsgPrefix[pri] && *rpmlogMsgPrefix[pri])
195 (void) fputs(_(rpmlogMsgPrefix[pri]), msgout);
197 (void) fputs(msg, msgout);
198 (void) fflush(msgout);
199 msgbuf = _free(msgbuf);
200 if (pri <= RPMLOG_CRIT)
204 void rpmlog (int code, const char *fmt, ...)
209 vrpmlog(code, fmt, ap);
213 int rpmErrorCode(void)
218 const char * rpmErrorString(void)
220 return rpmlogMessage();
223 rpmlogCallback rpmErrorSetCallback(rpmlogCallback cb)
225 return rpmlogSetCallback(cb);