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
00129 static char *rpmlogMsgPrefix[] = {
00130 N_("fatal error: "),
00131 N_("fatal error: "),
00132 N_("fatal error: "),
00133 N_("error: "),
00134 N_("warning: "),
00135 "",
00136 "",
00137 "D: ",
00138 };
00139
00140
00141 #if !defined(HAVE_VSNPRINTF)
00142 static inline int vsnprintf(char * buf, int nb,
00143 const char * fmt, va_list ap)
00144 {
00145 return vsprintf(buf, fmt, ap);
00146 }
00147 #endif
00148
00149
00150
00151
00152 static void vrpmlog (unsigned code, const char *fmt, va_list ap)
00153
00154
00155 {
00156 unsigned pri = RPMLOG_PRI(code);
00157 unsigned mask = RPMLOG_MASK(pri);
00158 unsigned fac = RPMLOG_FAC(code);
00159 char *msgbuf, *msg;
00160 int msgnb = BUFSIZ, nb;
00161 FILE * msgout = stderr;
00162
00163 if ((mask & rpmlogMask) == 0)
00164 return;
00165
00166
00167 msgbuf = xmalloc(msgnb);
00168 *msgbuf = '\0';
00169
00170
00171 while (1) {
00172 va_list apc;
00173 va_copy(apc, ap);
00174 nb = vsnprintf(msgbuf, msgnb, fmt, apc);
00175 if (nb > -1 && nb < msgnb)
00176 break;
00177 if (nb > -1)
00178 msgnb = nb+1;
00179 else
00180 msgnb *= 2;
00181 msgbuf = xrealloc(msgbuf, msgnb);
00182 }
00183 msgbuf[msgnb - 1] = '\0';
00184 msg = msgbuf;
00185
00186
00187
00188 if (pri <= RPMLOG_WARNING) {
00189
00190 if (recs == NULL)
00191 recs = xmalloc((nrecs+2) * sizeof(*recs));
00192 else
00193 recs = xrealloc(recs, (nrecs+2) * sizeof(*recs));
00194 recs[nrecs].code = code;
00195 recs[nrecs].message = msg = xrealloc(msgbuf, strlen(msgbuf)+1);
00196 msgbuf = NULL;
00197 recs[nrecs+1].code = 0;
00198 recs[nrecs+1].message = NULL;
00199 ++nrecs;
00200
00201 if (_rpmlogCallback) {
00202
00203 _rpmlogCallback();
00204
00205 return;
00206 }
00207 }
00208
00209
00210
00211
00212
00213 switch (pri) {
00214 case RPMLOG_INFO:
00215 case RPMLOG_NOTICE:
00216 msgout = stdout;
00217 break;
00218
00219 case RPMLOG_EMERG:
00220 case RPMLOG_ALERT:
00221 case RPMLOG_CRIT:
00222 case RPMLOG_ERR:
00223 case RPMLOG_WARNING:
00224 case RPMLOG_DEBUG:
00225 break;
00226 }
00227
00228 if (rpmlogMsgPrefix[pri] && *rpmlogMsgPrefix[pri])
00229 (void) fputs(_(rpmlogMsgPrefix[pri]), msgout);
00230
00231 (void) fputs(msg, msgout);
00232 (void) fflush(msgout);
00233 msgbuf = _free(msgbuf);
00234 if (pri <= RPMLOG_CRIT)
00235 exit(EXIT_FAILURE);
00236 }
00237
00238
00239
00240 void rpmlog (int code, const char *fmt, ...)
00241 {
00242 va_list ap;
00243
00244 va_start(ap, fmt);
00245
00246 vrpmlog(code, fmt, ap);
00247
00248 va_end(ap);
00249 }
00250
00251 int rpmErrorCode(void)
00252 {
00253 return rpmlogCode();
00254 }
00255
00256 const char * rpmErrorString(void)
00257 {
00258 return rpmlogMessage();
00259 }
00260
00261 rpmlogCallback rpmErrorSetCallback(rpmlogCallback cb)
00262 {
00263 return rpmlogSetCallback(cb);
00264 }
00265