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