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,
00094 int option,
00095 int facility)
00096 {
00097 }
00098
00099
00100 static unsigned rpmlogMask = RPMLOG_UPTO( RPMLOG_NOTICE );
00101
00102 #if 0
00103
00104 static unsigned rpmlogFacility = RPMLOG_USER;
00105 #endif
00106
00107 int rpmlogSetMask (int mask)
00108
00109
00110 {
00111 int omask = rpmlogMask;
00112 if (mask)
00113 rpmlogMask = mask;
00114 return omask;
00115 }
00116
00117
00118 static rpmlogCallback _rpmlogCallback;
00119
00120
00121 static rpmlogCallbackData _rpmlogCallbackData;
00122
00123 rpmlogCallback rpmlogSetCallback(rpmlogCallback cb, rpmlogCallbackData data)
00124
00125
00126 {
00127 rpmlogCallback ocb = _rpmlogCallback;
00128 _rpmlogCallback = cb;
00129 _rpmlogCallbackData = data;
00130 return ocb;
00131 }
00132
00133 void rpmlogGetCallback(rpmlogCallback *cb, rpmlogCallbackData *data)
00134
00135 {
00136 *cb = _rpmlogCallback;
00137 *data = _rpmlogCallbackData;
00138 return;
00139 }
00140
00141
00142 static FILE * _stdlog = NULL;
00143
00144 static int rpmlogDefault(rpmlogRec rec)
00145
00146
00147 {
00148 FILE *msgout = (_stdlog ? _stdlog : stderr);
00149
00150 switch (rec->pri) {
00151 case RPMLOG_INFO:
00152 case RPMLOG_NOTICE:
00153 msgout = (_stdlog ? _stdlog : stdout);
00154 break;
00155 case RPMLOG_EMERG:
00156 case RPMLOG_ALERT:
00157 case RPMLOG_CRIT:
00158 case RPMLOG_ERR:
00159 case RPMLOG_WARNING:
00160 case RPMLOG_DEBUG:
00161 default:
00162 break;
00163 }
00164
00165 (void) fputs(rpmlogLevelPrefix(rec->pri), msgout);
00166
00167 if (rec->message)
00168 (void) fputs(rec->message, msgout);
00169 (void) fflush(msgout);
00170
00171 return (rec->pri <= RPMLOG_CRIT ? RPMLOG_EXIT : 0);
00172 }
00173
00174 FILE * rpmlogSetFile(FILE * fp)
00175
00176
00177 {
00178 FILE * ofp = _stdlog;
00179 _stdlog = fp;
00180 return ofp;
00181 }
00182
00183
00184
00185 static const char *rpmlogMsgPrefix[] = {
00186 N_("fatal error: "),
00187 N_("fatal error: "),
00188 N_("fatal error: "),
00189 N_("error: "),
00190 N_("warning: "),
00191 "",
00192 "",
00193 "D: ",
00194 };
00195
00196
00197 const char * rpmlogLevelPrefix(rpmlogLvl pri)
00198 {
00199 return rpmlogMsgPrefix[pri&0x7];
00200 }
00201
00202 #if !defined(HAVE_VSNPRINTF)
00203 static inline int vsnprintf(char * buf, int nb,
00204 const char * fmt, va_list ap)
00205 {
00206 return vsprintf(buf, fmt, ap);
00207 }
00208 #endif
00209
00210
00211
00212
00213 void vrpmlog (unsigned code, const char *fmt, va_list ap)
00214
00215
00216 {
00217 unsigned pri = RPMLOG_PRI(code);
00218 unsigned mask = RPMLOG_MASK(pri);
00219 #if 0
00220 unsigned fac = RPMLOG_FAC(code);
00221 #endif
00222 char *msgbuf, *msg;
00223 size_t msgnb = BUFSIZ;
00224 int nb;
00225 int cbrc = RPMLOG_DEFAULT;
00226 int needexit = 0;
00227 struct rpmlogRec_s rec;
00228
00229 if ((mask & rpmlogMask) == 0)
00230 return;
00231
00232 msgbuf = xmalloc(msgnb);
00233 *msgbuf = '\0';
00234
00235
00236 while (1) {
00237 va_list apc;
00238 va_copy(apc, ap);
00239 nb = vsnprintf(msgbuf, msgnb, fmt, apc);
00240 if (nb > -1 && (size_t)nb < msgnb)
00241 break;
00242 if (nb > -1)
00243 msgnb = nb+1;
00244 else
00245 msgnb *= 2;
00246 msgbuf = xrealloc(msgbuf, msgnb);
00247
00248 va_end(apc);
00249
00250 }
00251 msgbuf[msgnb - 1] = '\0';
00252 msg = msgbuf;
00253
00254 rec.code = code;
00255 rec.message = msg;
00256 rec.pri = pri;
00257
00258
00259 if (pri <= RPMLOG_WARNING) {
00260 if (recs == NULL)
00261 recs = xmalloc((nrecs+2) * sizeof(*recs));
00262 else
00263 recs = xrealloc(recs, (nrecs+2) * sizeof(*recs));
00264 recs[nrecs].code = rec.code;
00265 recs[nrecs].pri = rec.pri;
00266 recs[nrecs].message = xstrdup(msgbuf);
00267 ++nrecs;
00268 recs[nrecs].code = 0;
00269 recs[nrecs].pri = 0;
00270 recs[nrecs].message = NULL;
00271 }
00272
00273 if (_rpmlogCallback) {
00274 cbrc = _rpmlogCallback(&rec, _rpmlogCallbackData);
00275 needexit += cbrc & RPMLOG_EXIT;
00276 }
00277
00278 if (cbrc & RPMLOG_DEFAULT) {
00279
00280 cbrc = rpmlogDefault(&rec);
00281
00282 needexit += cbrc & RPMLOG_EXIT;
00283 }
00284
00285
00286 msgbuf = _free(msgbuf);
00287
00288 if (needexit)
00289 exit(EXIT_FAILURE);
00290 }
00291
00292
00293
00294 void _rpmlog (int code, const char *fmt, ...)
00295 {
00296 va_list ap;
00297
00298 va_start(ap, fmt);
00299
00300 vrpmlog(code, fmt, ap);
00301
00302 va_end(ap);
00303 }