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