Go to the documentation of this file.00001
00005 #include "system.h"
00006 #include <stdarg.h>
00007 #define _RPMLOG_INTERNAL
00008 #include <rpmlog.h>
00009 #include "debug.h"
00010
00011
00012
00013
00014 static int nrecs = 0;
00015
00016 static rpmlogRec recs = NULL;
00017
00023 static inline void *
00024 _free( const void * p)
00025 {
00026 if (p != NULL) free((void *)p);
00027 return NULL;
00028 }
00029
00030 int rpmlogGetNrecs(void)
00031 {
00032 return nrecs;
00033 }
00034
00035 int rpmlogCode(void)
00036 {
00037 if (recs != NULL && nrecs > 0)
00038 return recs[nrecs-1].code;
00039 return -1;
00040 }
00041
00042 const char * rpmlogMessage(void)
00043 {
00044 if (recs != NULL && nrecs > 0)
00045 return recs[nrecs-1].message;
00046 return _("(no error)");
00047 }
00048
00049 const char * rpmlogRecMessage(rpmlogRec rec)
00050 {
00051 assert(rec != NULL);
00052 return (rec->message);
00053 }
00054
00055 rpmlogLvl rpmlogRecPriority(rpmlogRec rec)
00056 {
00057 assert(rec != NULL);
00058 return (rec->pri);
00059 }
00060
00061
00062 void rpmlogPrint(FILE *f)
00063 {
00064 int i;
00065
00066 if (f == NULL)
00067 f = stderr;
00068
00069 if (recs)
00070 for (i = 0; i < nrecs; i++) {
00071 rpmlogRec rec = recs + i;
00072 if (rec->message && *rec->message)
00073 fprintf(f, " %s", rec->message);
00074 }
00075 }
00076
00077
00078 void rpmlogClose (void)
00079
00080
00081 {
00082 int i;
00083
00084 if (recs)
00085 for (i = 0; i < nrecs; i++) {
00086 rpmlogRec rec = recs + i;
00087 rec->message = _free(rec->message);
00088 }
00089 recs = _free(recs);
00090 nrecs = 0;
00091 }
00092
00093 void rpmlogOpen ( const char *ident, int option,
00094 int facility)
00095 {
00096 }
00097
00098
00099 static unsigned rpmlogMask = RPMLOG_UPTO( RPMLOG_NOTICE );
00100
00101 #if 0
00102
00103 static unsigned rpmlogFacility = RPMLOG_USER;
00104 #endif
00105
00106 int rpmlogSetMask (int mask)
00107
00108
00109 {
00110 int omask = rpmlogMask;
00111 if (mask)
00112 rpmlogMask = mask;
00113 return omask;
00114 }
00115
00116
00117 static rpmlogCallback _rpmlogCallback = NULL;
00118
00119
00120 static rpmlogCallbackData _rpmlogCallbackData = NULL;
00121
00122 rpmlogCallback rpmlogSetCallback(rpmlogCallback cb, rpmlogCallbackData data)
00123
00124
00125 {
00126 rpmlogCallback ocb = _rpmlogCallback;
00127 _rpmlogCallback = cb;
00128 _rpmlogCallbackData = data;
00129 return ocb;
00130 }
00131
00132 void rpmlogGetCallback(rpmlogCallback *cb, rpmlogCallbackData *data)
00133
00134 {
00135 *cb = _rpmlogCallback;
00136 *data = _rpmlogCallbackData;
00137 return;
00138 }
00139
00140
00141 static FILE * _stdlog = NULL;
00142
00143 static int rpmlogDefault(rpmlogRec rec)
00144
00145
00146 {
00147 FILE *msgout = (_stdlog ? _stdlog : stderr);
00148
00149 switch (rec->pri) {
00150 case RPMLOG_INFO:
00151 case RPMLOG_NOTICE:
00152 msgout = (_stdlog ? _stdlog : stdout);
00153 break;
00154 case RPMLOG_EMERG:
00155 case RPMLOG_ALERT:
00156 case RPMLOG_CRIT:
00157 case RPMLOG_ERR:
00158 case RPMLOG_WARNING:
00159 case RPMLOG_DEBUG:
00160 default:
00161 break;
00162 }
00163
00164 (void) fputs(rpmlogLevelPrefix(rec->pri), msgout);
00165
00166 if (rec->message)
00167 (void) fputs(rec->message, msgout);
00168 (void) fflush(msgout);
00169
00170 return (rec->pri <= RPMLOG_CRIT ? RPMLOG_EXIT : 0);
00171 }
00172
00173 FILE * rpmlogSetFile(FILE * fp)
00174
00175
00176 {
00177 FILE * ofp = _stdlog;
00178 _stdlog = fp;
00179 return ofp;
00180 }
00181
00182
00183
00184 static const char *rpmlogMsgPrefix[] = {
00185 N_("fatal error: "),
00186 N_("fatal error: "),
00187 N_("fatal error: "),
00188 N_("error: "),
00189 N_("warning: "),
00190 "",
00191 "",
00192 "D: ",
00193 };
00194
00195
00196 const char * rpmlogLevelPrefix(rpmlogLvl pri)
00197 {
00198 return rpmlogMsgPrefix[pri&0x7];
00199 }
00200
00201 #if !defined(HAVE_VSNPRINTF)
00202 static inline int vsnprintf(char * buf, int nb,
00203 const char * fmt, va_list ap)
00204 {
00205 return vsprintf(buf, fmt, ap);
00206 }
00207 #endif
00208
00209
00210
00211
00212 static void vrpmlog (unsigned code, const char *fmt, va_list ap)
00213
00214
00215 {
00216 unsigned pri = RPMLOG_PRI(code);
00217 unsigned mask = RPMLOG_MASK(pri);
00218 #if 0
00219 unsigned fac = RPMLOG_FAC(code);
00220 #endif
00221 char *msgbuf, *msg;
00222 size_t msgnb = BUFSIZ;
00223 int nb;
00224 int cbrc = RPMLOG_DEFAULT;
00225 int needexit = 0;
00226 struct rpmlogRec_s rec;
00227
00228 if ((mask & rpmlogMask) == 0)
00229 return;
00230
00231 msgbuf = xmalloc(msgnb);
00232 *msgbuf = '\0';
00233
00234
00235 while (1) {
00236 va_list apc;
00237 va_copy(apc, ap);
00238 nb = vsnprintf(msgbuf, msgnb, fmt, apc);
00239 if (nb > -1 && (size_t)nb < msgnb)
00240 break;
00241 if (nb > -1)
00242 msgnb = nb+1;
00243 else
00244 msgnb *= 2;
00245 msgbuf = xrealloc(msgbuf, msgnb);
00246
00247 va_end(apc);
00248
00249 }
00250 msgbuf[msgnb - 1] = '\0';
00251 msg = msgbuf;
00252
00253 rec.code = code;
00254 rec.message = msg;
00255 rec.pri = pri;
00256
00257
00258 if (pri <= RPMLOG_WARNING) {
00259 if (recs == NULL)
00260 recs = xmalloc((nrecs+2) * sizeof(*recs));
00261 else
00262 recs = xrealloc(recs, (nrecs+2) * sizeof(*recs));
00263 recs[nrecs].code = rec.code;
00264 recs[nrecs].pri = rec.pri;
00265 recs[nrecs].message = xstrdup(msgbuf);
00266 recs[nrecs+1].code = 0;
00267 recs[nrecs].pri = 0;
00268 recs[nrecs+1].message = NULL;
00269 ++nrecs;
00270 }
00271
00272 if (_rpmlogCallback) {
00273 cbrc = _rpmlogCallback(&rec, _rpmlogCallbackData);
00274 needexit += cbrc & RPMLOG_EXIT;
00275 }
00276
00277 if (cbrc & RPMLOG_DEFAULT) {
00278
00279 cbrc = rpmlogDefault(&rec);
00280
00281 needexit += cbrc & RPMLOG_EXIT;
00282 }
00283
00284
00285 msgbuf = _free(msgbuf);
00286
00287 if (needexit)
00288 exit(EXIT_FAILURE);
00289 }
00290
00291
00292
00293 void rpmlog (int code, const char *fmt, ...)
00294 {
00295 va_list ap;
00296
00297 va_start(ap, fmt);
00298
00299 vrpmlog(code, fmt, ap);
00300
00301 va_end(ap);
00302 }